diff options
author | John Ross | 2013-04-30 17:21:41 +0000 |
---|---|---|
committer | Thomas Watson | 2013-04-30 21:31:45 +0000 |
commit | 49dfed19867fd47adef6640340531aa84fbe23ca (patch) | |
tree | 8fb3dcd2ac251bf8cbc8fee078f0dd772e90620b | |
parent | ae3a4191cdfaec7da10a3ccc97578b5499f05285 (diff) | |
download | rt.equinox.framework-49dfed19867fd47adef6640340531aa84fbe23ca.tar.gz rt.equinox.framework-49dfed19867fd47adef6640340531aa84fbe23ca.tar.xz rt.equinox.framework-49dfed19867fd47adef6640340531aa84fbe23ca.zip |
Bug 406936 - [rfc 191] Grant implied import package permissions to woven
bundles with dynamic imports.
Check that the weaver has PackagePermission[pkg,IMPORT] when adding or
setting anything to the DynamicImportList.
Other modifications to the list currently do not require this permission
but still require AdminPermission[bundle,WEAVE].
Add dedicated method to BundlePermissions for adding permissions to
woven bundles. A PackagePermission with an action of
IMPORT must be used. These permissions are tracked in their own
Permissions collection and are now part of the implies check.
WovenClassImpl grants the permissions right after transitioning to
TRANSFORMED but before adding the imports to the
BundleLoader. The ProtectionDomain is gotten by casting the bundle
wiring revision to ModuleRevision and then the revision
info to Generation. The permissions of the protection domain are then
cast to BundlePermissions.
3 files changed, 61 insertions, 15 deletions
diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/permadmin/BundlePermissions.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/permadmin/BundlePermissions.java index 5ade23ff0..e27ec4d10 100644 --- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/permadmin/BundlePermissions.java +++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/permadmin/BundlePermissions.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2008, 2010 IBM Corporation and others. + * Copyright (c) 2008, 2013 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -10,11 +10,11 @@ *******************************************************************************/ package org.eclipse.osgi.internal.permadmin; -import java.security.Permission; -import java.security.PermissionCollection; +import java.security.*; import java.util.Enumeration; import java.util.NoSuchElementException; import org.osgi.framework.Bundle; +import org.osgi.framework.PackagePermission; public final class BundlePermissions extends PermissionCollection { private static final long serialVersionUID = -5443618108312606612L; @@ -34,12 +34,14 @@ public final class BundlePermissions extends PermissionCollection { private final SecurityAdmin securityAdmin; private final PermissionInfoCollection impliedPermissions; private final PermissionInfoCollection restrictedPermissions; + private final Permissions wovenPermissions; public BundlePermissions(Bundle bundle, SecurityAdmin securityAdmin, PermissionInfoCollection impliedPermissions, PermissionInfoCollection restrictedPermissions) { this.bundle = bundle; this.securityAdmin = securityAdmin; this.impliedPermissions = impliedPermissions; this.restrictedPermissions = restrictedPermissions; + this.wovenPermissions = new Permissions(); setReadOnly(); // collections are managed with ConditionalPermissionAdmin } @@ -47,6 +49,22 @@ public final class BundlePermissions extends PermissionCollection { throw new SecurityException(); } + /** + * Add a package permission to this woven bundle. + * <p/> + * Bundles may require additional permissions in order to execute byte code + * woven by weaving hooks. + * + * @param permission The package permission to add to this woven bundle. + * @throws SecurityException If the <code>permission</code> + * does not have an action of {@link PackagePermission#IMPORT}. + */ + public void addWovenPermission(PackagePermission permission) { + if (!permission.getActions().equals(PackagePermission.IMPORT)) + throw new SecurityException(); + wovenPermissions.add(permission); + } + public Enumeration<Permission> elements() { // TODO return an empty enumeration for now; // It does not seem possible to do this properly with multiple exports and conditional permissions. @@ -58,9 +76,15 @@ public final class BundlePermissions extends PermissionCollection { // first check implied permissions if ((impliedPermissions != null) && impliedPermissions.implies(permission)) return true; + + // Now check implied permissions added by weaving hooks. + if (wovenPermissions.implies(permission)) + return true; + // We must be allowed by the restricted permissions to have any hope of passing the check if ((restrictedPermissions != null) && !restrictedPermissions.implies(permission)) return false; + return securityAdmin.checkPermission(permission, this); } diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/weaving/DynamicImportList.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/weaving/DynamicImportList.java index 0a425e3dd..7c6f4f070 100644 --- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/weaving/DynamicImportList.java +++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/weaving/DynamicImportList.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2010, 2012 IBM Corporation and others. + * Copyright (c) 2010, 2013 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -13,6 +13,7 @@ package org.eclipse.osgi.internal.weaving; import java.util.*; import org.eclipse.osgi.util.ManifestElement; import org.osgi.framework.Constants; +import org.osgi.framework.PackagePermission; /** * A list of DynamicImport-Package statements that are to be used for adding new @@ -42,14 +43,14 @@ public class DynamicImportList extends AbstractList<String> implements RandomAcc @Override public String set(int index, String element) { wovenClass.checkPermission(); - validateSyntax(element); + validateSyntaxAndCheckPackagePermission(element); return imports.set(index, element); } @Override public void add(int index, String element) { wovenClass.checkPermission(); - validateSyntax(element); + validateSyntaxAndCheckPackagePermission(element); imports.add(index, element); } @@ -59,15 +60,21 @@ public class DynamicImportList extends AbstractList<String> implements RandomAcc return imports.remove(index); } - private void validateSyntax(String imported) { - // validate the syntax of imports that are added. + private void validateSyntaxAndCheckPackagePermission(String dynamicImportPackageDescription) { + ManifestElement[] clauses; + // Validate the syntax of imports that are added. try { - ManifestElement.parseHeader(Constants.IMPORT_PACKAGE, imported); - } catch (Throwable t) { - IllegalArgumentException exception = new IllegalArgumentException(); - exception.initCause(t); - throw exception; + clauses = ManifestElement.parseHeader(Constants.IMPORT_PACKAGE, dynamicImportPackageDescription); + } catch (Exception e) { + throw new IllegalArgumentException(e); } - return; + SecurityManager sm = System.getSecurityManager(); + if (sm == null) + return; + // Security is enabled. Ensure the weaver has import package permission + // for each dynamic import added. + for (ManifestElement clause : clauses) + for (String pkg : clause.getValueComponents()) + sm.checkPermission(new PackagePermission(pkg, PackagePermission.IMPORT)); } } diff --git a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/weaving/WovenClassImpl.java b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/weaving/WovenClassImpl.java index 20ab0691f..6351b9677 100644 --- a/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/weaving/WovenClassImpl.java +++ b/bundles/org.eclipse.osgi/container/src/org/eclipse/osgi/internal/weaving/WovenClassImpl.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2010, 2012 IBM Corporation and others. + * Copyright (c) 2010, 2013 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -12,10 +12,13 @@ package org.eclipse.osgi.internal.weaving; import java.security.*; import java.util.*; +import org.eclipse.osgi.container.ModuleRevision; import org.eclipse.osgi.internal.framework.EquinoxContainer; import org.eclipse.osgi.internal.loader.BundleLoader; +import org.eclipse.osgi.internal.permadmin.BundlePermissions; import org.eclipse.osgi.internal.serviceregistry.HookContext; import org.eclipse.osgi.internal.serviceregistry.ServiceRegistry; +import org.eclipse.osgi.storage.BundleInfo.Generation; import org.eclipse.osgi.storage.StorageUtil; import org.eclipse.osgi.storage.bundlefile.BundleEntry; import org.eclipse.osgi.util.ManifestElement; @@ -267,6 +270,9 @@ public final class WovenClassImpl implements WovenClass, HookContext { for (String newImport : newImports) { try { ManifestElement[] importElements = ManifestElement.parseHeader(Constants.IMPORT_PACKAGE, newImport); + // Grant implied import package permissions for all dynamic + // import packages to the woven bundle. + addImpliedImportPackagePermissions(importElements); loader.addDynamicImportPackage(importElements); } catch (BundleException e) { // should not have happened; checked at add. @@ -277,6 +283,15 @@ public final class WovenClassImpl implements WovenClass, HookContext { return wovenBytes; } + private void addImpliedImportPackagePermissions(ManifestElement[] importElements) { + if (System.getSecurityManager() == null) + return; + ProtectionDomain wovenDomain = ((Generation) ((ModuleRevision) getBundleWiring().getRevision()).getRevisionInfo()).getDomain(); + for (ManifestElement clause : importElements) + for (String pkg : clause.getValueComponents()) + ((BundlePermissions) wovenDomain.getPermissions()).addWovenPermission(new PackagePermission(pkg, PackagePermission.IMPORT)); + } + public String toString() { return className; } |