3789983e89
Reviewed-by: darcy, ihse
274 lines
11 KiB
Java
274 lines
11 KiB
Java
/*
|
|
* Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved.
|
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
|
*
|
|
* This code is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License version 2 only, as
|
|
* published by the Free Software Foundation.
|
|
*
|
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
* version 2 for more details (a copy is included in the LICENSE file that
|
|
* accompanied this code).
|
|
*
|
|
* You should have received a copy of the GNU General Public License version
|
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
|
*
|
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
|
* or visit www.oracle.com if you need additional information or have any
|
|
* questions.
|
|
*/
|
|
|
|
/*
|
|
* @test
|
|
* @bug 8164705 8168410
|
|
* @summary check compatibility after FilePermission change
|
|
* @library /java/security/testlibrary/
|
|
* @modules java.base/jdk.internal.misc
|
|
* @run main CompatImpact prepare
|
|
* @run main CompatImpact builtin
|
|
* @run main/othervm -Djdk.security.filePermCompat=true CompatImpact mine
|
|
* @run main/fail CompatImpact mine
|
|
* @run main CompatImpact dopriv
|
|
*/
|
|
|
|
import java.io.File;
|
|
import java.io.FilePermission;
|
|
import java.nio.file.Files;
|
|
import java.nio.file.Paths;
|
|
import java.security.AccessController;
|
|
import java.security.AllPermission;
|
|
import java.security.CodeSource;
|
|
import java.security.Permission;
|
|
import java.security.PermissionCollection;
|
|
import java.security.Policy;
|
|
import java.security.PrivilegedAction;
|
|
import java.security.ProtectionDomain;
|
|
import java.security.SecurityPermission;
|
|
|
|
public class CompatImpact {
|
|
|
|
public static void main(String[] args) throws Exception {
|
|
switch (args[0]) {
|
|
// copy class files to future classpath
|
|
case "prepare":
|
|
// cp in .
|
|
String cp = System.getProperty("test.classes");
|
|
Files.copy(Paths.get(cp, "CompatImpact.class"),
|
|
Paths.get("CompatImpact.class"));
|
|
Files.copy(Paths.get(cp, "CompatImpact$MP.class"),
|
|
Paths.get("CompatImpact$MP.class"));
|
|
Files.write(Paths.get("f"), new byte[10]);
|
|
// cp in ./sub
|
|
Files.createDirectory(Paths.get("sub"));
|
|
Files.copy(Paths.get(cp, "CompatImpact.class"),
|
|
Paths.get("sub", "CompatImpact.class"));
|
|
Files.copy(Paths.get(cp, "CompatImpact$MP.class"),
|
|
Paths.get("sub", "CompatImpact$MP.class"));
|
|
Files.write(Paths.get("sub", "f"), new byte[10]);
|
|
// cp in ./inner
|
|
Files.createDirectory(Paths.get("inner"));
|
|
Files.copy(Paths.get(cp, "CompatImpact$DoPrivInner.class"),
|
|
Paths.get("inner", "CompatImpact$DoPrivInner.class"));
|
|
break;
|
|
// default policy always covered, user-defined depends on
|
|
// system property jdk.security.filePermCompact.
|
|
case "builtin":
|
|
case "mine":
|
|
cp = System.getProperty("test.classes");
|
|
Proc p;
|
|
String failed = "";
|
|
String testcase = "";
|
|
String cwd = System.getProperty("user.dir");
|
|
|
|
// Granting a FilePermission on an absolute path
|
|
testcase = "PonA";
|
|
p = p(args[0], cwd + "/f")
|
|
.args("f", cwd + "/f")
|
|
.debug(testcase)
|
|
.start();
|
|
if (p.waitFor() != 0) {
|
|
Files.copy(Paths.get("stderr." + testcase), System.out);
|
|
failed += testcase + " ";
|
|
}
|
|
|
|
// Granting a FilePermission on a relative path
|
|
testcase = "PonR";
|
|
p = p(args[0], "f")
|
|
.args("f", cwd + "/f")
|
|
.debug(testcase)
|
|
.start();
|
|
if (p.waitFor() != 0) {
|
|
Files.copy(Paths.get("stderr." + testcase), System.out);
|
|
failed += testcase + " ";
|
|
}
|
|
|
|
// Reading file on classpath, not cwd
|
|
testcase = "cp";
|
|
String cprel = Paths.get(cwd).relativize(Paths.get(cp))
|
|
.normalize().toString();
|
|
p = p(args[0], "x")
|
|
.args(cp + "/f", cprel + "/f")
|
|
.debug(testcase)
|
|
.start();
|
|
if (p.waitFor() != 0) {
|
|
Files.copy(Paths.get("stderr." + testcase), System.out);
|
|
failed += testcase + " ";
|
|
}
|
|
|
|
// Reading file on classpath, cwd
|
|
testcase = "cpHere";
|
|
p = p(args[0], "x")
|
|
.args(cwd + "/f", "f", "RES")
|
|
.cp(".") // Must! cancel the old CLASSPATH.
|
|
.debug(testcase)
|
|
.start();
|
|
if (p.waitFor() != 0) {
|
|
Files.copy(Paths.get("stderr." + testcase), System.out);
|
|
failed += testcase + " ";
|
|
}
|
|
|
|
// Reading file on classpath, cwd
|
|
testcase = "cpSub";
|
|
p = p(args[0], "x")
|
|
.args(cwd + "/sub/f", "sub/f", "RES")
|
|
.cp("sub") // Must! There's CLASSPATH.
|
|
.debug(testcase)
|
|
.start();
|
|
if (p.waitFor() != 0) {
|
|
Files.copy(Paths.get("stderr." + testcase), System.out);
|
|
failed += testcase + " ";
|
|
}
|
|
|
|
if (!failed.isEmpty()) {
|
|
throw new Exception(failed + "failed");
|
|
}
|
|
break;
|
|
// test <policy_type> <grant> <read...>
|
|
case "test":
|
|
if (args[1].equals("mine")) {
|
|
Policy.setPolicy(new MP(args[2]));
|
|
}
|
|
Exception e = null;
|
|
for (int i = 3; i < args.length; i++) {
|
|
try {
|
|
System.out.println(args[i]);
|
|
if (args[i].equals("RES")) {
|
|
CompatImpact.class.getResourceAsStream("f")
|
|
.close();
|
|
} else {
|
|
new File(args[i]).exists();
|
|
}
|
|
} catch (Exception e2) {
|
|
e = e2;
|
|
e2.printStackTrace(System.out);
|
|
}
|
|
}
|
|
if (e != null) {
|
|
System.err.println("====================");
|
|
throw e;
|
|
}
|
|
break;
|
|
// doPrivWithPerm test launcher
|
|
case "dopriv":
|
|
cwd = System.getProperty("user.dir");
|
|
// caller (CompatImpact doprivouter, no permission) in sub,
|
|
// executor (DoPrivInner, AllPermission) in inner.
|
|
p = Proc.create("CompatImpact")
|
|
.args("doprivouter")
|
|
.prop("java.security.manager", "")
|
|
.grant(new File("inner"))
|
|
.perm(new AllPermission())
|
|
.cp("sub", "inner")
|
|
.debug("doPriv")
|
|
.args(cwd)
|
|
.start();
|
|
if (p.waitFor() != 0) {
|
|
throw new Exception("dopriv test fails");
|
|
}
|
|
break;
|
|
// doprivouter <cwd>
|
|
case "doprivouter":
|
|
DoPrivInner.main(args);
|
|
break;
|
|
default:
|
|
throw new Exception("unknown " + args[0]);
|
|
}
|
|
}
|
|
|
|
// Call by CompatImpact doprivouter, with AllPermission
|
|
public static class DoPrivInner {
|
|
public static void main(String[] args) throws Exception {
|
|
AccessController.doPrivileged((PrivilegedAction<Boolean>)
|
|
() -> new File("x").exists(),
|
|
null,
|
|
new FilePermission(args[1] + "/x", "read"));
|
|
AccessController.doPrivileged((PrivilegedAction<Boolean>)
|
|
() -> new File(args[1] + "/x").exists(),
|
|
null,
|
|
new FilePermission("x", "read"));
|
|
try {
|
|
AccessController.doPrivileged((PrivilegedAction<Boolean>)
|
|
() -> new File("x").exists(),
|
|
null,
|
|
new FilePermission("y", "read"));
|
|
throw new Exception("Should not read");
|
|
} catch (SecurityException se) {
|
|
// Expected
|
|
}
|
|
}
|
|
}
|
|
|
|
// Return a Proc object for different policy types
|
|
private static Proc p(String type, String f) throws Exception {
|
|
Proc p = Proc.create("CompatImpact")
|
|
.prop("java.security.manager", "")
|
|
.inheritProp("jdk.security.filePermCompat");
|
|
p.args("test", type);
|
|
switch (type) {
|
|
case "builtin":
|
|
// For builtin policy, reading access to f can be
|
|
// granted as a permission
|
|
p.perm(new FilePermission(f, "read"));
|
|
p.args("-");
|
|
break;
|
|
case "mine":
|
|
// For my policy, f is passed into test and new MP(f)
|
|
// will be set as new policy
|
|
p.perm(new SecurityPermission("setPolicy"));
|
|
p.args(f);
|
|
break;
|
|
default:
|
|
throw new Exception("unknown " + type);
|
|
}
|
|
return p;
|
|
}
|
|
|
|
// My own Policy impl, with only one granted permission, also not smart
|
|
// enough to know whether ProtectionDomain grants any permission
|
|
static class MP extends Policy {
|
|
final PermissionCollection pc;
|
|
MP(String f) {
|
|
FilePermission p = new FilePermission(f, "read");
|
|
pc = p.newPermissionCollection();
|
|
pc.add(p);
|
|
}
|
|
@Override
|
|
public PermissionCollection getPermissions(CodeSource codesource) {
|
|
return pc;
|
|
}
|
|
|
|
@Override
|
|
public PermissionCollection getPermissions(ProtectionDomain domain) {
|
|
return pc;
|
|
}
|
|
|
|
@Override
|
|
public boolean implies(ProtectionDomain domain, Permission permission) {
|
|
return pc.implies(permission);
|
|
}
|
|
}
|
|
}
|