Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Watson2021-02-26 14:46:31 +0000
committerThomas Watson2021-02-26 14:47:16 +0000
commitd60755236727ba69734922858db966f316bf5936 (patch)
tree6ee9998463c82b9a4e05b289aebad1b6364652d3
parent3429a5e7aaafbad00a933ffcd91d77345d0446bd (diff)
downloadrt.equinox.framework-I20210227-0600.tar.gz
rt.equinox.framework-I20210227-0600.tar.xz
rt.equinox.framework-I20210227-0600.zip
Because permission instances can be infinite the evaluationCache can grow unbounded leading to a memory leak. This is a quick fix to cap the cache at 10000. A better approach may be to use some weak reference cache in the future, but for now we need to stop the uncontrolled leak. A test is added that does 10 million different file permission checks. On my system this grinds to a halt after about 8 million checks. With the cap at 10000 the 10 million permission checks happen <15 seconds. Change-Id: I6e18d4d6fcab274bb2f56c69a6e0893f8e474418 Signed-off-by: Thomas Watson <tjwatson@us.ibm.com>
-rw-r--r--bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/securityadmin/SecurityAdminUnitTests.java23
-rw-r--r--bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/permadmin/SecurityTable.java3
2 files changed, 26 insertions, 0 deletions
diff --git a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/securityadmin/SecurityAdminUnitTests.java b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/securityadmin/SecurityAdminUnitTests.java
index 3935b9eb1..5e61766cb 100644
--- a/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/securityadmin/SecurityAdminUnitTests.java
+++ b/bundles/org.eclipse.osgi.tests/src/org/eclipse/osgi/tests/securityadmin/SecurityAdminUnitTests.java
@@ -1160,6 +1160,29 @@ public class SecurityAdminUnitTests extends AbstractBundleTests {
testPermission(acc, new FilePermission(relativeExecutable.getAbsolutePath(), "execute"), true);
}
+ public void testPermissionCheckCache() {
+ // test single row with signer condition
+ ConditionalPermissionUpdate update = cpa.newConditionalPermissionUpdate();
+ List rows = update.getConditionalPermissionInfos();
+ rows.add(cpa.newConditionalPermissionInfo(null, new ConditionInfo[] { SIGNER_CONDITION1 }, READONLY_INFOS,
+ ConditionalPermissionInfo.ALLOW));
+ assertTrue("failed to commit", update.commit()); //$NON-NLS-1$
+
+ AccessControlContext acc = cpa.getAccessControlContext(new String[] { "cn=t1,c=FR;cn=test1,c=US" }); //$NON-NLS-1$
+
+ for (int i = 0; i < 10000000; i++) {
+ try {
+ if (i % 1000 == 0) {
+ System.out.println("i=" + i);
+ }
+ acc.checkPermission(new FilePermission("test" + i, "read")); //$NON-NLS-1$ //$NON-NLS-2$
+ } catch (AccessControlException e) {
+ fail("Unexpected AccessControlExcetpion", e); //$NON-NLS-1$
+ }
+ }
+
+ }
+
private void checkInfos(ConditionalPermissionInfo testInfo1, ConditionalPermissionInfo testInfo2) {
assertTrue("Infos are not equal: " + testInfo1.getEncoded() + " " + testInfo2.getEncoded(), testInfo1.equals(testInfo2));
assertEquals("Info hash code is not equal", testInfo1.hashCode(), testInfo2.hashCode());
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/permadmin/SecurityTable.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/permadmin/SecurityTable.java
index ff32046ac..7fc0837a2 100644
--- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/permadmin/SecurityTable.java
+++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/permadmin/SecurityTable.java
@@ -51,6 +51,9 @@ public class SecurityTable extends PermissionCollection {
if (bundlePermissions == null) {
return ABSTAIN;
}
+ if (evaluationCache.size() > 10000) {
+ clearEvaluationCache();
+ }
EvaluationCacheKey evaluationCacheKey = new EvaluationCacheKey(bundlePermissions, permission);
if (isEmpty()) {
evaluationCache.put(evaluationCacheKey, ABSTAIN);

Back to the top