1 /* 2 * Copyright (c) 2016, 2017, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24 /* 25 * @test 26 * @bug 8164705 8168410 27 * @summary check compatibility after FilePermission change 28 * @library /java/security/testlibrary/ 29 * @modules java.base/jdk.internal.misc 30 * @run main CompatImpact prepare 31 * @run main CompatImpact builtin 32 * @run main/othervm -Djdk.security.filePermCompat=true CompatImpact mine 33 * @run main/fail CompatImpact mine 34 * @run main CompatImpact dopriv 35 */ 36 37 import java.io.File; 38 import java.io.FilePermission; 39 import java.nio.file.Files; 40 import java.nio.file.Paths; 41 import java.security.AccessController; 42 import java.security.AllPermission; 43 import java.security.CodeSource; 44 import java.security.Permission; 45 import java.security.PermissionCollection; 46 import java.security.Policy; 47 import java.security.PrivilegedAction; 48 import java.security.ProtectionDomain; 49 import java.security.SecurityPermission; 50 51 public class CompatImpact { 52 main(String[] args)53 public static void main(String[] args) throws Exception { 54 switch (args[0]) { 55 // copy class files to future classpath 56 case "prepare": 57 // cp in . 58 String cp = System.getProperty("test.classes"); 59 Files.copy(Paths.get(cp, "CompatImpact.class"), 60 Paths.get("CompatImpact.class")); 61 Files.copy(Paths.get(cp, "CompatImpact$MP.class"), 62 Paths.get("CompatImpact$MP.class")); 63 Files.write(Paths.get("f"), new byte[10]); 64 // cp in ./sub 65 Files.createDirectory(Paths.get("sub")); 66 Files.copy(Paths.get(cp, "CompatImpact.class"), 67 Paths.get("sub", "CompatImpact.class")); 68 Files.copy(Paths.get(cp, "CompatImpact$MP.class"), 69 Paths.get("sub", "CompatImpact$MP.class")); 70 Files.write(Paths.get("sub", "f"), new byte[10]); 71 // cp in ./inner 72 Files.createDirectory(Paths.get("inner")); 73 Files.copy(Paths.get(cp, "CompatImpact$DoPrivInner.class"), 74 Paths.get("inner", "CompatImpact$DoPrivInner.class")); 75 break; 76 // default policy always covered, user-defined depends on 77 // system property jdk.security.filePermCompact. 78 case "builtin": 79 case "mine": 80 cp = System.getProperty("test.classes"); 81 Proc p; 82 String failed = ""; 83 String testcase = ""; 84 String cwd = System.getProperty("user.dir"); 85 86 // Granting a FilePermission on an absolute path 87 testcase = "PonA"; 88 p = p(args[0], cwd + "/f") 89 .args("f", cwd + "/f") 90 .debug(testcase) 91 .start(); 92 if (p.waitFor() != 0) { 93 Files.copy(Paths.get("stderr." + testcase), System.out); 94 failed += testcase + " "; 95 } 96 97 // Granting a FilePermission on a relative path 98 testcase = "PonR"; 99 p = p(args[0], "f") 100 .args("f", cwd + "/f") 101 .debug(testcase) 102 .start(); 103 if (p.waitFor() != 0) { 104 Files.copy(Paths.get("stderr." + testcase), System.out); 105 failed += testcase + " "; 106 } 107 108 // Reading file on classpath, not cwd 109 testcase = "cp"; 110 String cprel = Paths.get(cwd).relativize(Paths.get(cp)) 111 .normalize().toString(); 112 p = p(args[0], "x") 113 .args(cp + "/f", cprel + "/f") 114 .debug(testcase) 115 .start(); 116 if (p.waitFor() != 0) { 117 Files.copy(Paths.get("stderr." + testcase), System.out); 118 failed += testcase + " "; 119 } 120 121 // Reading file on classpath, cwd 122 testcase = "cpHere"; 123 p = p(args[0], "x") 124 .args(cwd + "/f", "f", "RES") 125 .cp(".") // Must! cancel the old CLASSPATH. 126 .debug(testcase) 127 .start(); 128 if (p.waitFor() != 0) { 129 Files.copy(Paths.get("stderr." + testcase), System.out); 130 failed += testcase + " "; 131 } 132 133 // Reading file on classpath, cwd 134 testcase = "cpSub"; 135 p = p(args[0], "x") 136 .args(cwd + "/sub/f", "sub/f", "RES") 137 .cp("sub") // Must! There's CLASSPATH. 138 .debug(testcase) 139 .start(); 140 if (p.waitFor() != 0) { 141 Files.copy(Paths.get("stderr." + testcase), System.out); 142 failed += testcase + " "; 143 } 144 145 if (!failed.isEmpty()) { 146 throw new Exception(failed + "failed"); 147 } 148 break; 149 // test <policy_type> <grant> <read...> 150 case "test": 151 if (args[1].equals("mine")) { 152 Policy.setPolicy(new MP(args[2])); 153 } 154 Exception e = null; 155 for (int i = 3; i < args.length; i++) { 156 try { 157 System.out.println(args[i]); 158 if (args[i].equals("RES")) { 159 CompatImpact.class.getResourceAsStream("f") 160 .close(); 161 } else { 162 new File(args[i]).exists(); 163 } 164 } catch (Exception e2) { 165 e = e2; 166 e2.printStackTrace(System.out); 167 } 168 } 169 if (e != null) { 170 System.err.println("===================="); 171 throw e; 172 } 173 break; 174 // doPrivWithPerm test launcher 175 case "dopriv": 176 cwd = System.getProperty("user.dir"); 177 // caller (CompatImpact doprivouter, no permission) in sub, 178 // executor (DoPrivInner, AllPermission) in inner. 179 p = Proc.create("CompatImpact") 180 .args("doprivouter") 181 .prop("java.security.manager", "") 182 .grant(new File("inner")) 183 .perm(new AllPermission()) 184 .cp("sub", "inner") 185 .debug("doPriv") 186 .args(cwd) 187 .start(); 188 if (p.waitFor() != 0) { 189 throw new Exception("dopriv test fails"); 190 } 191 break; 192 // doprivouter <cwd> 193 case "doprivouter": 194 DoPrivInner.main(args); 195 break; 196 default: 197 throw new Exception("unknown " + args[0]); 198 } 199 } 200 201 // Call by CompatImpact doprivouter, with AllPermission 202 public static class DoPrivInner { main(String[] args)203 public static void main(String[] args) throws Exception { 204 AccessController.doPrivileged((PrivilegedAction<Boolean>) 205 () -> new File("x").exists(), 206 null, 207 new FilePermission(args[1] + "/x", "read")); 208 AccessController.doPrivileged((PrivilegedAction<Boolean>) 209 () -> new File(args[1] + "/x").exists(), 210 null, 211 new FilePermission("x", "read")); 212 try { 213 AccessController.doPrivileged((PrivilegedAction<Boolean>) 214 () -> new File("x").exists(), 215 null, 216 new FilePermission("y", "read")); 217 throw new Exception("Should not read"); 218 } catch (SecurityException se) { 219 // Expected 220 } 221 } 222 } 223 224 // Return a Proc object for different policy types p(String type, String f)225 private static Proc p(String type, String f) throws Exception { 226 Proc p = Proc.create("CompatImpact") 227 .prop("java.security.manager", "") 228 .inheritProp("jdk.security.filePermCompat"); 229 p.args("test", type); 230 switch (type) { 231 case "builtin": 232 // For builtin policy, reading access to f can be 233 // granted as a permission 234 p.perm(new FilePermission(f, "read")); 235 p.args("-"); 236 break; 237 case "mine": 238 // For my policy, f is passed into test and new MP(f) 239 // will be set as new policy 240 p.perm(new SecurityPermission("setPolicy")); 241 p.args(f); 242 break; 243 default: 244 throw new Exception("unknown " + type); 245 } 246 return p; 247 } 248 249 // My own Policy impl, with only one granted permission, also not smart 250 // enough to know whether ProtectionDomain grants any permission 251 static class MP extends Policy { 252 final PermissionCollection pc; MP(String f)253 MP(String f) { 254 FilePermission p = new FilePermission(f, "read"); 255 pc = p.newPermissionCollection(); 256 pc.add(p); 257 } 258 @Override getPermissions(CodeSource codesource)259 public PermissionCollection getPermissions(CodeSource codesource) { 260 return pc; 261 } 262 263 @Override getPermissions(ProtectionDomain domain)264 public PermissionCollection getPermissions(ProtectionDomain domain) { 265 return pc; 266 } 267 268 @Override implies(ProtectionDomain domain, Permission permission)269 public boolean implies(ProtectionDomain domain, Permission permission) { 270 return pc.implies(permission); 271 } 272 } 273 } 274