1/* 2 * Copyright (c) 2009, 2015, 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/* @test 25 * @bug 6866804 7006126 8028270 8065109 26 * @summary Unit test for java.nio.file.Files 27 * @library .. 28 * @build CheckPermissions 29 * @run main/othervm CheckPermissions 30 */ 31 32import java.nio.ByteBuffer; 33import java.nio.file.*; 34import static java.nio.file.Files.*; 35import static java.nio.file.StandardOpenOption.*; 36import java.nio.file.attribute.*; 37import java.nio.channels.SeekableByteChannel; 38import java.security.Permission; 39import java.io.*; 40import java.nio.charset.StandardCharsets; 41import java.util.*; 42 43/** 44 * Checks each method that accesses the file system does the right permission 45 * check when there is a security manager set. 46 */ 47 48public class CheckPermissions { 49 50 static class Checks { 51 private List<Permission> permissionsChecked = new ArrayList<>(); 52 private Set<String> propertiesChecked = new HashSet<>(); 53 private List<String> readsChecked = new ArrayList<>(); 54 private List<String> writesChecked = new ArrayList<>(); 55 private List<String> deletesChecked = new ArrayList<>(); 56 private List<String> execsChecked = new ArrayList<>(); 57 58 List<Permission> permissionsChecked() { return permissionsChecked; } 59 Set<String> propertiesChecked() { return propertiesChecked; } 60 List<String> readsChecked() { return readsChecked; } 61 List<String> writesChecked() { return writesChecked; } 62 List<String> deletesChecked() { return deletesChecked; } 63 List<String> execsChecked() { return execsChecked; } 64 } 65 66 static ThreadLocal<Checks> myChecks = 67 new ThreadLocal<Checks>() { 68 @Override protected Checks initialValue() { 69 return null; 70 } 71 }; 72 73 static void prepare() { 74 myChecks.set(new Checks()); 75 } 76 77 static void assertCheckPermission(Permission expected) { 78 if (!myChecks.get().permissionsChecked().contains(expected)) 79 throw new RuntimeException(expected + " not checked"); 80 } 81 82 static void assertCheckPropertyAccess(String key) { 83 if (!myChecks.get().propertiesChecked().contains(key)) 84 throw new RuntimeException("Property " + key + " not checked"); 85 } 86 87 static void assertChecked(Path file, List<String> list) { 88 String s = file.toString(); 89 for (String f: list) { 90 if (f.endsWith(s)) 91 return; 92 } 93 throw new RuntimeException("Access not checked"); 94 } 95 96 static void assertCheckRead(Path file) { 97 assertChecked(file, myChecks.get().readsChecked()); 98 } 99 100 static void assertCheckWrite(Path file) { 101 assertChecked(file, myChecks.get().writesChecked()); 102 } 103 104 static void assertCheckWriteToDirectory(Path dir) { 105 String s = dir.toString(); 106 List<String> list = myChecks.get().writesChecked(); 107 for (String f: list) { 108 if (f.startsWith(s)) { 109 return; 110 } 111 } 112 throw new RuntimeException("Access not checked"); 113 } 114 115 static void assertCheckDelete(Path file) { 116 assertChecked(file, myChecks.get().deletesChecked()); 117 } 118 119 static void assertCheckExec(Path file) { 120 assertChecked(file, myChecks.get().execsChecked()); 121 } 122 123 static class LoggingSecurityManager extends SecurityManager { 124 static void install() { 125 System.setSecurityManager(new LoggingSecurityManager()); 126 } 127 128 @Override 129 public void checkPermission(Permission perm) { 130 Checks checks = myChecks.get(); 131 if (checks != null) 132 checks.permissionsChecked().add(perm); 133 } 134 135 @Override 136 public void checkPropertyAccess(String key) { 137 Checks checks = myChecks.get(); 138 if (checks != null) 139 checks.propertiesChecked().add(key); 140 } 141 142 @Override 143 public void checkRead(String file) { 144 Checks checks = myChecks.get(); 145 if (checks != null) 146 checks.readsChecked().add(file); 147 } 148 149 @Override 150 public void checkWrite(String file) { 151 Checks checks = myChecks.get(); 152 if (checks != null) 153 checks.writesChecked().add(file); 154 } 155 156 @Override 157 public void checkDelete(String file) { 158 Checks checks = myChecks.get(); 159 if (checks != null) 160 checks.deletesChecked().add(file); 161 } 162 163 @Override 164 public void checkExec(String file) { 165 Checks checks = myChecks.get(); 166 if (checks != null) 167 checks.execsChecked().add(file); 168 } 169 } 170 171 static void testBasicFileAttributeView(BasicFileAttributeView view, Path file) 172 throws IOException 173 { 174 prepare(); 175 view.readAttributes(); 176 assertCheckRead(file); 177 178 prepare(); 179 FileTime now = FileTime.fromMillis(System.currentTimeMillis()); 180 view.setTimes(null, now, now); 181 assertCheckWrite(file); 182 } 183 184 static void testPosixFileAttributeView(PosixFileAttributeView view, Path file) 185 throws IOException 186 { 187 prepare(); 188 PosixFileAttributes attrs = view.readAttributes(); 189 assertCheckRead(file); 190 assertCheckPermission(new RuntimePermission("accessUserInformation")); 191 192 prepare(); 193 view.setPermissions(attrs.permissions()); 194 assertCheckWrite(file); 195 assertCheckPermission(new RuntimePermission("accessUserInformation")); 196 197 prepare(); 198 view.setOwner(attrs.owner()); 199 assertCheckWrite(file); 200 assertCheckPermission(new RuntimePermission("accessUserInformation")); 201 202 prepare(); 203 view.setOwner(attrs.owner()); 204 assertCheckWrite(file); 205 assertCheckPermission(new RuntimePermission("accessUserInformation")); 206 } 207 208 public static void main(String[] args) throws IOException { 209 final Path testdir = Paths.get(System.getProperty("test.dir", ".")).toAbsolutePath(); 210 final Path tmpdir = Paths.get(System.getProperty("java.io.tmpdir")); 211 212 Path file = createFile(testdir.resolve("file1234")); 213 try { 214 LoggingSecurityManager.install(); 215 216 // -- check access -- 217 218 prepare(); 219 exists(file); 220 assertCheckRead(file); 221 222 prepare(); 223 isReadable(file); 224 assertCheckRead(file); 225 226 prepare(); 227 isWritable(file); 228 assertCheckWrite(file); 229 230 prepare(); 231 isExecutable(file); 232 assertCheckExec(file); 233 234 // -- copy -- 235 236 Path target = testdir.resolve("target1234"); 237 prepare(); 238 copy(file, target); 239 try { 240 assertCheckRead(file); 241 assertCheckWrite(target); 242 } finally { 243 delete(target); 244 } 245 246 if (TestUtil.supportsLinks(testdir)) { 247 Path link = testdir.resolve("link1234"); 248 createSymbolicLink(link, file); 249 try { 250 prepare(); 251 copy(link, target, LinkOption.NOFOLLOW_LINKS); 252 try { 253 assertCheckRead(link); 254 assertCheckWrite(target); 255 assertCheckPermission(new LinkPermission("symbolic")); 256 } finally { 257 delete(target); 258 } 259 260 prepare(); 261 readSymbolicLink(link); 262 assertCheckPermission(new FilePermission(link.toString(), "readlink")); 263 } finally { 264 delete(link); 265 } 266 } 267 268 // -- createDirectory -- 269 270 Path subdir = testdir.resolve("subdir1234"); 271 prepare(); 272 createDirectory(subdir); 273 try { 274 assertCheckWrite(subdir); 275 } finally { 276 delete(subdir); 277 } 278 279 // -- createFile -- 280 281 Path fileToCreate = testdir.resolve("file7890"); 282 prepare(); 283 createFile(fileToCreate); 284 try { 285 assertCheckWrite(fileToCreate); 286 } finally { 287 delete(fileToCreate); 288 } 289 290 // -- createSymbolicLink -- 291 292 if (TestUtil.supportsLinks(testdir)) { 293 prepare(); 294 Path link = testdir.resolve("link1234"); 295 createSymbolicLink(link, file); 296 try { 297 assertCheckWrite(link); 298 assertCheckPermission(new LinkPermission("symbolic")); 299 } finally { 300 delete(link); 301 } 302 } 303 304 // -- createLink -- 305 306 if (TestUtil.supportsLinks(testdir)) { 307 prepare(); 308 Path link = testdir.resolve("entry234"); 309 createLink(link, file); 310 try { 311 assertCheckWrite(link); 312 assertCheckPermission(new LinkPermission("hard")); 313 } finally { 314 delete(link); 315 } 316 } 317 318 // -- createTempFile -- 319 320 prepare(); 321 Path tmpfile1 = createTempFile("foo", null); 322 try { 323 assertCheckWriteToDirectory(tmpdir); 324 } finally { 325 delete(tmpfile1); 326 } 327 prepare(); 328 Path tmpfile2 = createTempFile(testdir, "foo", ".tmp"); 329 try { 330 assertCheckWriteToDirectory(testdir); 331 } finally { 332 delete(tmpfile2); 333 } 334 335 // -- createTempDirectory -- 336 337 prepare(); 338 Path tmpdir1 = createTempDirectory("foo"); 339 try { 340 assertCheckWriteToDirectory(tmpdir); 341 } finally { 342 delete(tmpdir1); 343 } 344 prepare(); 345 Path tmpdir2 = createTempDirectory(testdir, "foo"); 346 try { 347 assertCheckWriteToDirectory(testdir); 348 } finally { 349 delete(tmpdir2); 350 } 351 352 // -- delete/deleteIfExists -- 353 354 Path fileToDelete = testdir.resolve("file7890"); 355 356 createFile(fileToDelete); 357 prepare(); 358 delete(fileToDelete); 359 assertCheckDelete(fileToDelete); 360 361 createFile(fileToDelete); 362 prepare(); 363 deleteIfExists(fileToDelete); // file exists 364 assertCheckDelete(fileToDelete); 365 366 prepare(); 367 deleteIfExists(fileToDelete); // file does not exist 368 assertCheckDelete(fileToDelete); 369 370 // -- exists/notExists -- 371 372 prepare(); 373 exists(file); 374 assertCheckRead(file); 375 376 prepare(); 377 notExists(file); 378 assertCheckRead(file); 379 380 // -- getFileStore -- 381 382 prepare(); 383 getFileStore(file); 384 assertCheckRead(file); 385 assertCheckPermission(new RuntimePermission("getFileStoreAttributes")); 386 387 // -- isSameFile -- 388 389 prepare(); 390 isSameFile(file, testdir); 391 assertCheckRead(file); 392 assertCheckRead(testdir); 393 394 // -- move -- 395 396 Path target2 = testdir.resolve("target1234"); 397 prepare(); 398 move(file, target2); 399 try { 400 assertCheckWrite(file); 401 assertCheckWrite(target2); 402 } finally { 403 // restore file 404 move(target2, file); 405 } 406 407 // -- newByteChannel -- 408 409 prepare(); 410 try (SeekableByteChannel sbc = newByteChannel(file)) { 411 assertCheckRead(file); 412 } 413 prepare(); 414 try (SeekableByteChannel sbc = newByteChannel(file, WRITE)) { 415 assertCheckWrite(file); 416 } 417 prepare(); 418 try (SeekableByteChannel sbc = newByteChannel(file, READ, WRITE)) { 419 assertCheckRead(file); 420 assertCheckWrite(file); 421 } 422 423 prepare(); 424 try (SeekableByteChannel sbc = newByteChannel(file, DELETE_ON_CLOSE)) { 425 assertCheckRead(file); 426 assertCheckDelete(file); 427 } 428 createFile(file); // restore file 429 430 // -- newBufferedReader/newBufferedWriter -- 431 432 prepare(); 433 try (BufferedReader br = newBufferedReader(file)) { 434 assertCheckRead(file); 435 } 436 437 prepare(); 438 try (BufferedWriter bw = newBufferedWriter(file, WRITE)) { 439 assertCheckWrite(file); 440 } 441 442 prepare(); 443 try (BufferedWriter bw = newBufferedWriter(file, DELETE_ON_CLOSE)) { 444 assertCheckWrite(file); 445 assertCheckDelete(file); 446 } 447 createFile(file); // restore file 448 449 prepare(); 450 try (BufferedWriter bw = newBufferedWriter(file, 451 StandardCharsets.UTF_16, WRITE)) { 452 assertCheckWrite(file); 453 } 454 455 prepare(); 456 try (BufferedWriter bw = newBufferedWriter(file, 457 StandardCharsets.UTF_16, DELETE_ON_CLOSE)) { 458 assertCheckWrite(file); 459 assertCheckDelete(file); 460 } 461 createFile(file); // restore file 462 463 // -- newInputStream/newOutputStream -- 464 465 prepare(); 466 try (InputStream in = newInputStream(file)) { 467 assertCheckRead(file); 468 } 469 prepare(); 470 try (OutputStream out = newOutputStream(file)) { 471 assertCheckWrite(file); 472 } 473 474 // -- write -- 475 476 prepare(); 477 Files.write(file, new byte[]{(byte) 42, (byte) 666}, WRITE); 478 assertCheckWrite(file); 479 480 prepare(); 481 Files.write(file, new byte[]{(byte) 42, (byte) 666}, WRITE, 482 DELETE_ON_CLOSE); 483 assertCheckWrite(file); 484 assertCheckDelete(file); 485 createFile(file); // restore file 486 487 List<String> lines = Arrays.asList("42", "666"); 488 489 prepare(); 490 Files.write(file, lines, StandardCharsets.UTF_16, WRITE); 491 assertCheckWrite(file); 492 493 prepare(); 494 Files.write(file, lines, StandardCharsets.UTF_16, WRITE, 495 DELETE_ON_CLOSE); 496 assertCheckWrite(file); 497 assertCheckDelete(file); 498 createFile(file); // restore file 499 500 prepare(); 501 Files.write(file, lines, WRITE); 502 assertCheckWrite(file); 503 504 prepare(); 505 Files.write(file, lines, WRITE, DELETE_ON_CLOSE); 506 assertCheckWrite(file); 507 assertCheckDelete(file); 508 createFile(file); // restore file 509 510 // -- newDirectoryStream -- 511 512 prepare(); 513 try (DirectoryStream<Path> stream = newDirectoryStream(testdir)) { 514 assertCheckRead(testdir); 515 516 if (stream instanceof SecureDirectoryStream<?>) { 517 Path entry; 518 SecureDirectoryStream<Path> sds = 519 (SecureDirectoryStream<Path>)stream; 520 521 // newByteChannel 522 entry = file.getFileName(); 523 prepare(); 524 try (SeekableByteChannel sbc = sds.newByteChannel(entry, EnumSet.of(READ))) { 525 assertCheckRead(file); 526 } 527 prepare(); 528 try (SeekableByteChannel sbc = sds.newByteChannel(entry, EnumSet.of(WRITE))) { 529 assertCheckWrite(file); 530 } 531 532 // deleteFile 533 entry = file.getFileName(); 534 prepare(); 535 sds.deleteFile(entry); 536 assertCheckDelete(file); 537 createFile(testdir.resolve(entry)); // restore file 538 539 // deleteDirectory 540 entry = Paths.get("subdir1234"); 541 createDirectory(testdir.resolve(entry)); 542 prepare(); 543 sds.deleteDirectory(entry); 544 assertCheckDelete(testdir.resolve(entry)); 545 546 // move 547 entry = Paths.get("tempname1234"); 548 prepare(); 549 sds.move(file.getFileName(), sds, entry); 550 assertCheckWrite(file); 551 assertCheckWrite(testdir.resolve(entry)); 552 sds.move(entry, sds, file.getFileName()); // restore file 553 554 // newDirectoryStream 555 entry = Paths.get("subdir1234"); 556 createDirectory(testdir.resolve(entry)); 557 try { 558 prepare(); 559 sds.newDirectoryStream(entry).close(); 560 assertCheckRead(testdir.resolve(entry)); 561 } finally { 562 delete(testdir.resolve(entry)); 563 } 564 565 // getFileAttributeView to access attributes of directory 566 testBasicFileAttributeView(sds 567 .getFileAttributeView(BasicFileAttributeView.class), testdir); 568 testPosixFileAttributeView(sds 569 .getFileAttributeView(PosixFileAttributeView.class), testdir); 570 571 // getFileAttributeView to access attributes of entry 572 entry = file.getFileName(); 573 testBasicFileAttributeView(sds 574 .getFileAttributeView(entry, BasicFileAttributeView.class), file); 575 testPosixFileAttributeView(sds 576 .getFileAttributeView(entry, PosixFileAttributeView.class), file); 577 578 } else { 579 System.out.println("SecureDirectoryStream not tested"); 580 } 581 } 582 583 // -- toAbsolutePath -- 584 585 prepare(); 586 file.getFileName().toAbsolutePath(); 587 assertCheckPropertyAccess("user.dir"); 588 589 // -- toRealPath -- 590 591 prepare(); 592 file.toRealPath(); 593 assertCheckRead(file); 594 595 prepare(); 596 file.toRealPath(LinkOption.NOFOLLOW_LINKS); 597 assertCheckRead(file); 598 599 prepare(); 600 Paths.get(".").toRealPath(); 601 assertCheckPropertyAccess("user.dir"); 602 603 prepare(); 604 Paths.get(".").toRealPath(LinkOption.NOFOLLOW_LINKS); 605 assertCheckPropertyAccess("user.dir"); 606 607 // -- register -- 608 609 try (WatchService watcher = FileSystems.getDefault().newWatchService()) { 610 prepare(); 611 testdir.register(watcher, StandardWatchEventKinds.ENTRY_DELETE); 612 assertCheckRead(testdir); 613 } 614 615 // -- getAttribute/setAttribute/readAttributes -- 616 617 prepare(); 618 getAttribute(file, "size"); 619 assertCheckRead(file); 620 621 prepare(); 622 setAttribute(file, "lastModifiedTime", 623 FileTime.fromMillis(System.currentTimeMillis())); 624 assertCheckWrite(file); 625 626 prepare(); 627 readAttributes(file, "*"); 628 assertCheckRead(file); 629 630 // -- BasicFileAttributeView -- 631 testBasicFileAttributeView( 632 getFileAttributeView(file, BasicFileAttributeView.class), file); 633 634 // -- PosixFileAttributeView -- 635 636 { 637 PosixFileAttributeView view = 638 getFileAttributeView(file, PosixFileAttributeView.class); 639 if (view != null && 640 getFileStore(file).supportsFileAttributeView(PosixFileAttributeView.class)) 641 { 642 testPosixFileAttributeView(view, file); 643 } else { 644 System.out.println("PosixFileAttributeView not tested"); 645 } 646 } 647 648 // -- DosFileAttributeView -- 649 650 { 651 DosFileAttributeView view = 652 getFileAttributeView(file, DosFileAttributeView.class); 653 if (view != null && 654 getFileStore(file).supportsFileAttributeView(DosFileAttributeView.class)) 655 { 656 prepare(); 657 view.readAttributes(); 658 assertCheckRead(file); 659 660 prepare(); 661 view.setArchive(false); 662 assertCheckWrite(file); 663 664 prepare(); 665 view.setHidden(false); 666 assertCheckWrite(file); 667 668 prepare(); 669 view.setReadOnly(false); 670 assertCheckWrite(file); 671 672 prepare(); 673 view.setSystem(false); 674 assertCheckWrite(file); 675 } else { 676 System.out.println("DosFileAttributeView not tested"); 677 } 678 } 679 680 // -- FileOwnerAttributeView -- 681 682 { 683 FileOwnerAttributeView view = 684 getFileAttributeView(file, FileOwnerAttributeView.class); 685 if (view != null && 686 getFileStore(file).supportsFileAttributeView(FileOwnerAttributeView.class)) 687 { 688 prepare(); 689 UserPrincipal owner = view.getOwner(); 690 assertCheckRead(file); 691 assertCheckPermission(new RuntimePermission("accessUserInformation")); 692 693 prepare(); 694 view.setOwner(owner); 695 assertCheckWrite(file); 696 assertCheckPermission(new RuntimePermission("accessUserInformation")); 697 698 } else { 699 System.out.println("FileOwnerAttributeView not tested"); 700 } 701 } 702 703 // -- UserDefinedFileAttributeView -- 704 705 { 706 UserDefinedFileAttributeView view = 707 getFileAttributeView(file, UserDefinedFileAttributeView.class); 708 if (view != null && 709 getFileStore(file).supportsFileAttributeView(UserDefinedFileAttributeView.class)) 710 { 711 prepare(); 712 view.write("test", ByteBuffer.wrap(new byte[100])); 713 assertCheckWrite(file); 714 assertCheckPermission(new RuntimePermission("accessUserDefinedAttributes")); 715 716 prepare(); 717 view.read("test", ByteBuffer.allocate(100)); 718 assertCheckRead(file); 719 assertCheckPermission(new RuntimePermission("accessUserDefinedAttributes")); 720 721 prepare(); 722 view.size("test"); 723 assertCheckRead(file); 724 assertCheckPermission(new RuntimePermission("accessUserDefinedAttributes")); 725 726 prepare(); 727 view.list(); 728 assertCheckRead(file); 729 assertCheckPermission(new RuntimePermission("accessUserDefinedAttributes")); 730 731 prepare(); 732 view.delete("test"); 733 assertCheckWrite(file); 734 assertCheckPermission(new RuntimePermission("accessUserDefinedAttributes")); 735 } else { 736 System.out.println("UserDefinedFileAttributeView not tested"); 737 } 738 } 739 740 // -- AclFileAttributeView -- 741 { 742 AclFileAttributeView view = 743 getFileAttributeView(file, AclFileAttributeView.class); 744 if (view != null && 745 getFileStore(file).supportsFileAttributeView(AclFileAttributeView.class)) 746 { 747 prepare(); 748 List<AclEntry> acl = view.getAcl(); 749 assertCheckRead(file); 750 assertCheckPermission(new RuntimePermission("accessUserInformation")); 751 prepare(); 752 view.setAcl(acl); 753 assertCheckWrite(file); 754 assertCheckPermission(new RuntimePermission("accessUserInformation")); 755 } else { 756 System.out.println("AclFileAttributeView not tested"); 757 } 758 } 759 760 // -- UserPrincipalLookupService 761 762 UserPrincipalLookupService lookupService = 763 FileSystems.getDefault().getUserPrincipalLookupService(); 764 UserPrincipal owner = getOwner(file); 765 766 prepare(); 767 lookupService.lookupPrincipalByName(owner.getName()); 768 assertCheckPermission(new RuntimePermission("lookupUserInformation")); 769 770 try { 771 UserPrincipal group = readAttributes(file, PosixFileAttributes.class).group(); 772 prepare(); 773 lookupService.lookupPrincipalByGroupName(group.getName()); 774 assertCheckPermission(new RuntimePermission("lookupUserInformation")); 775 } catch (UnsupportedOperationException ignore) { 776 System.out.println("lookupPrincipalByGroupName not tested"); 777 } 778 779 780 } finally { 781 deleteIfExists(file); 782 } 783 } 784} 785