23 * questions. |
23 * questions. |
24 */ |
24 */ |
25 |
25 |
26 package java.lang; |
26 package java.lang; |
27 |
27 |
28 import java.security.*; |
28 import java.lang.RuntimePermission; |
|
29 import java.lang.module.ModuleDescriptor; |
|
30 import java.lang.module.ModuleDescriptor.Exports; |
|
31 import java.lang.module.ModuleDescriptor.Opens; |
|
32 import java.lang.reflect.Layer; |
|
33 import java.lang.reflect.Member; |
|
34 import java.lang.reflect.Module; |
29 import java.io.FileDescriptor; |
35 import java.io.FileDescriptor; |
30 import java.io.File; |
36 import java.io.File; |
31 import java.io.FilePermission; |
37 import java.io.FilePermission; |
|
38 import java.net.InetAddress; |
|
39 import java.net.SocketPermission; |
|
40 import java.security.AccessControlContext; |
|
41 import java.security.AccessController; |
|
42 import java.security.Permission; |
|
43 import java.security.PrivilegedAction; |
|
44 import java.security.Security; |
|
45 import java.security.SecurityPermission; |
|
46 import java.util.HashSet; |
|
47 import java.util.Objects; |
32 import java.util.PropertyPermission; |
48 import java.util.PropertyPermission; |
33 import java.lang.RuntimePermission; |
49 import java.util.Set; |
34 import java.net.SocketPermission; |
50 import java.util.stream.Collectors; |
35 import java.net.NetPermission; |
51 import java.util.stream.Stream; |
36 import java.util.Hashtable; |
|
37 import java.net.InetAddress; |
|
38 import java.lang.reflect.*; |
|
39 import java.net.URL; |
|
40 |
52 |
41 import jdk.internal.reflect.CallerSensitive; |
53 import jdk.internal.reflect.CallerSensitive; |
42 import sun.security.util.SecurityConstants; |
54 import sun.security.util.SecurityConstants; |
43 |
55 |
44 /** |
56 /** |
1413 packages[i++] = s; |
1425 packages[i++] = s; |
1414 } |
1426 } |
1415 } |
1427 } |
1416 } |
1428 } |
1417 |
1429 |
1418 if (packages == null) |
1430 if (packages == null) { |
1419 packages = new String[0]; |
1431 packages = new String[0]; |
|
1432 } |
1420 return packages; |
1433 return packages; |
1421 } |
1434 } |
1422 |
1435 |
1423 /** |
1436 // The non-exported packages of the modules in the boot layer that are |
1424 * Throws a <code>SecurityException</code> if the |
1437 // loaded by the platform class loader or its ancestors. A non-exported |
1425 * calling thread is not allowed to access the package specified by |
1438 // package is a package that either is not exported at all by its containing |
1426 * the argument. |
1439 // module or is exported in a qualified fashion by its containing module. |
1427 * <p> |
1440 private static final Set<String> nonExportedPkgs; |
1428 * This method is used by the <code>loadClass</code> method of class |
1441 |
1429 * loaders. |
1442 static { |
1430 * <p> |
1443 // Get the modules in the boot layer |
1431 * This method first gets a list of |
1444 Stream<Module> bootLayerModules = Layer.boot().modules().stream(); |
1432 * restricted packages by obtaining a comma-separated list from |
1445 |
1433 * a call to |
1446 // Filter out the modules loaded by the boot or platform loader |
1434 * <code>java.security.Security.getProperty("package.access")</code>, |
1447 PrivilegedAction<Set<Module>> pa = () -> |
1435 * and checks to see if <code>pkg</code> starts with or equals |
1448 bootLayerModules.filter(SecurityManager::isBootOrPlatformModule) |
1436 * any of the restricted packages. If it does, then |
1449 .collect(Collectors.toSet()); |
1437 * <code>checkPermission</code> gets called with the |
1450 Set<Module> modules = AccessController.doPrivileged(pa); |
1438 * <code>RuntimePermission("accessClassInPackage."+pkg)</code> |
1451 |
1439 * permission. |
1452 // Filter out the non-exported packages |
1440 * <p> |
1453 nonExportedPkgs = modules.stream() |
1441 * If this method is overridden, then |
1454 .map(Module::getDescriptor) |
1442 * <code>super.checkPackageAccess</code> should be called |
1455 .map(SecurityManager::nonExportedPkgs) |
1443 * as the first line in the overridden method. |
1456 .flatMap(Set::stream) |
|
1457 .collect(Collectors.toSet()); |
|
1458 } |
|
1459 |
|
1460 /** |
|
1461 * Returns true if the module's loader is the boot or platform loader. |
|
1462 */ |
|
1463 private static boolean isBootOrPlatformModule(Module m) { |
|
1464 return m.getClassLoader() == null || |
|
1465 m.getClassLoader() == ClassLoader.getPlatformClassLoader(); |
|
1466 } |
|
1467 |
|
1468 /** |
|
1469 * Returns the non-exported packages of the specified module. |
|
1470 */ |
|
1471 private static Set<String> nonExportedPkgs(ModuleDescriptor md) { |
|
1472 // start with all packages in the module |
|
1473 Set<String> pkgs = new HashSet<>(md.packages()); |
|
1474 |
|
1475 // remove the non-qualified exported packages |
|
1476 md.exports().stream() |
|
1477 .filter(p -> !p.isQualified()) |
|
1478 .map(Exports::source) |
|
1479 .forEach(pkgs::remove); |
|
1480 |
|
1481 // remove the non-qualified open packages |
|
1482 md.opens().stream() |
|
1483 .filter(p -> !p.isQualified()) |
|
1484 .map(Opens::source) |
|
1485 .forEach(pkgs::remove); |
|
1486 |
|
1487 return pkgs; |
|
1488 } |
|
1489 |
|
1490 /** |
|
1491 * Throws a {@code SecurityException} if the calling thread is not allowed |
|
1492 * to access the specified package. |
|
1493 * <p> |
|
1494 * This method is called by the {@code loadClass} method of class loaders. |
|
1495 * <p> |
|
1496 * This method checks if the specified package starts with or equals |
|
1497 * any of the packages in the {@code package.access} Security Property. |
|
1498 * An implementation may also check the package against an additional |
|
1499 * list of restricted packages as noted below. If the package is restricted, |
|
1500 * {@link #checkPermission(Permission)} is called with a |
|
1501 * {@code RuntimePermission("accessClassInPackage."+pkg)} permission. |
|
1502 * <p> |
|
1503 * If this method is overridden, then {@code super.checkPackageAccess} |
|
1504 * should be called as the first line in the overridden method. |
|
1505 * |
|
1506 * @implNote |
|
1507 * This implementation also restricts all non-exported packages of modules |
|
1508 * loaded by {@linkplain ClassLoader#getPlatformClassLoader |
|
1509 * the platform class loader} or its ancestors. A "non-exported package" |
|
1510 * refers to a package that is not exported to all modules. Specifically, |
|
1511 * it refers to a package that either is not exported at all by its |
|
1512 * containing module or is exported in a qualified fashion by its |
|
1513 * containing module. |
1444 * |
1514 * |
1445 * @param pkg the package name. |
1515 * @param pkg the package name. |
1446 * @exception SecurityException if the calling thread does not have |
1516 * @throws SecurityException if the calling thread does not have |
1447 * permission to access the specified package. |
1517 * permission to access the specified package. |
1448 * @exception NullPointerException if the package name argument is |
1518 * @throws NullPointerException if the package name argument is |
1449 * <code>null</code>. |
1519 * {@code null}. |
1450 * @see java.lang.ClassLoader#loadClass(java.lang.String, boolean) |
1520 * @see java.lang.ClassLoader#loadClass(String, boolean) loadClass |
1451 * loadClass |
|
1452 * @see java.security.Security#getProperty getProperty |
1521 * @see java.security.Security#getProperty getProperty |
1453 * @see #checkPermission(java.security.Permission) checkPermission |
1522 * @see #checkPermission(Permission) checkPermission |
1454 */ |
1523 */ |
1455 public void checkPackageAccess(String pkg) { |
1524 public void checkPackageAccess(String pkg) { |
1456 if (pkg == null) { |
1525 Objects.requireNonNull(pkg, "package name can't be null"); |
1457 throw new NullPointerException("package name can't be null"); |
1526 |
|
1527 // check if pkg is not exported to all modules |
|
1528 if (nonExportedPkgs.contains(pkg)) { |
|
1529 checkPermission( |
|
1530 new RuntimePermission("accessClassInPackage." + pkg)); |
|
1531 return; |
1458 } |
1532 } |
1459 |
1533 |
1460 String[] restrictedPkgs; |
1534 String[] restrictedPkgs; |
1461 synchronized (packageAccessLock) { |
1535 synchronized (packageAccessLock) { |
1462 /* |
1536 /* |
1510 } |
1584 } |
1511 } |
1585 } |
1512 } |
1586 } |
1513 |
1587 |
1514 /** |
1588 /** |
1515 * Throws a <code>SecurityException</code> if the |
1589 * Throws a {@code SecurityException} if the calling thread is not |
1516 * calling thread is not allowed to define classes in the package |
1590 * allowed to define classes in the specified package. |
1517 * specified by the argument. |
1591 * <p> |
1518 * <p> |
1592 * This method is called by the {@code loadClass} method of some |
1519 * This method is used by the <code>loadClass</code> method of some |
|
1520 * class loaders. |
1593 * class loaders. |
1521 * <p> |
1594 * <p> |
1522 * This method first gets a list of restricted packages by |
1595 * This method checks if the specified package starts with or equals |
1523 * obtaining a comma-separated list from a call to |
1596 * any of the packages in the {@code package.definition} Security |
1524 * <code>java.security.Security.getProperty("package.definition")</code>, |
1597 * Property. An implementation may also check the package against an |
1525 * and checks to see if <code>pkg</code> starts with or equals |
1598 * additional list of restricted packages as noted below. If the package |
1526 * any of the restricted packages. If it does, then |
1599 * is restricted, {@link #checkPermission(Permission)} is called with a |
1527 * <code>checkPermission</code> gets called with the |
1600 * {@code RuntimePermission("defineClassInPackage."+pkg)} permission. |
1528 * <code>RuntimePermission("defineClassInPackage."+pkg)</code> |
1601 * <p> |
1529 * permission. |
1602 * If this method is overridden, then {@code super.checkPackageDefinition} |
1530 * <p> |
1603 * should be called as the first line in the overridden method. |
1531 * If this method is overridden, then |
1604 * |
1532 * <code>super.checkPackageDefinition</code> should be called |
1605 * @implNote |
1533 * as the first line in the overridden method. |
1606 * This implementation also restricts all non-exported packages of modules |
|
1607 * loaded by {@linkplain ClassLoader#getPlatformClassLoader |
|
1608 * the platform class loader} or its ancestors. A "non-exported package" |
|
1609 * refers to a package that is not exported to all modules. Specifically, |
|
1610 * it refers to a package that either is not exported at all by its |
|
1611 * containing module or is exported in a qualified fashion by its |
|
1612 * containing module. |
1534 * |
1613 * |
1535 * @param pkg the package name. |
1614 * @param pkg the package name. |
1536 * @exception SecurityException if the calling thread does not have |
1615 * @throws SecurityException if the calling thread does not have |
1537 * permission to define classes in the specified package. |
1616 * permission to define classes in the specified package. |
1538 * @see java.lang.ClassLoader#loadClass(java.lang.String, boolean) |
1617 * @throws NullPointerException if the package name argument is |
|
1618 * {@code null}. |
|
1619 * @see java.lang.ClassLoader#loadClass(String, boolean) |
1539 * @see java.security.Security#getProperty getProperty |
1620 * @see java.security.Security#getProperty getProperty |
1540 * @see #checkPermission(java.security.Permission) checkPermission |
1621 * @see #checkPermission(Permission) checkPermission |
1541 */ |
1622 */ |
1542 public void checkPackageDefinition(String pkg) { |
1623 public void checkPackageDefinition(String pkg) { |
1543 if (pkg == null) { |
1624 Objects.requireNonNull(pkg, "package name can't be null"); |
1544 throw new NullPointerException("package name can't be null"); |
1625 |
|
1626 // check if pkg is not exported to all modules |
|
1627 if (nonExportedPkgs.contains(pkg)) { |
|
1628 checkPermission( |
|
1629 new RuntimePermission("defineClassInPackage." + pkg)); |
|
1630 return; |
1545 } |
1631 } |
1546 |
1632 |
1547 String[] pkgs; |
1633 String[] pkgs; |
1548 synchronized (packageDefinitionLock) { |
1634 synchronized (packageDefinitionLock) { |
1549 /* |
1635 /* |