diff options
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; } |