6866804: (file) Path calls checkPermission insteadof checkXXX (sol)
Reviewed-by: sherman
--- a/jdk/src/solaris/classes/sun/nio/fs/UnixPath.java Thu Aug 20 08:42:38 2009 +0100
+++ b/jdk/src/solaris/classes/sun/nio/fs/UnixPath.java Thu Aug 20 08:48:29 2009 +0100
@@ -65,9 +65,6 @@
// array of offsets of elements in path (created lazily)
private volatile int[] offsets;
- // file permissions (created lazily)
- private volatile FilePermission[] perms;
-
UnixPath(UnixFileSystem fs, byte[] path) {
this.fs = fs;
this.path = path;
@@ -768,45 +765,23 @@
}
}
- // create file permissions used for read and write checks
- private void checkReadOrWrite(boolean checkRead) {
- SecurityManager sm = System.getSecurityManager();
- if (sm == null)
- return;
- if (perms == null) {
- synchronized (this) {
- if (perms == null) {
- FilePermission[] p = new FilePermission[2];
- String pathForPermCheck = getPathForPermissionCheck();
- p[0] = new FilePermission(pathForPermCheck,
- SecurityConstants.FILE_READ_ACTION);
- p[1] = new FilePermission(pathForPermCheck,
- SecurityConstants.FILE_WRITE_ACTION);
- perms = p;
- }
- }
- }
- if (checkRead) {
- sm.checkPermission(perms[0]);
- } else {
- sm.checkPermission(perms[1]);
- }
- }
void checkRead() {
- checkReadOrWrite(true);
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ sm.checkRead(getPathForPermissionCheck());
}
void checkWrite() {
- checkReadOrWrite(false);
+ SecurityManager sm = System.getSecurityManager();
+ if (sm != null)
+ sm.checkWrite(getPathForPermissionCheck());
}
void checkDelete() {
SecurityManager sm = System.getSecurityManager();
- if (sm != null) {
- // permission not cached
+ if (sm != null)
sm.checkDelete(getPathForPermissionCheck());
- }
}
@Override
--- a/jdk/src/windows/classes/sun/nio/fs/WindowsFileAttributeViews.java Thu Aug 20 08:42:38 2009 +0100
+++ b/jdk/src/windows/classes/sun/nio/fs/WindowsFileAttributeViews.java Thu Aug 20 08:48:29 2009 +0100
@@ -46,6 +46,7 @@
@Override
public WindowsFileAttributes readAttributes() throws IOException {
+ file.checkRead();
try {
return WindowsFileAttributes.get(file, followLinks);
} catch (WindowsException x) {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/jdk/test/java/nio/file/Path/CheckPermissions.java Thu Aug 20 08:48:29 2009 +0100
@@ -0,0 +1,695 @@
+/*
+ * Copyright 2009 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
+ * CA 95054 USA or visit www.sun.com if you need additional information or
+ * have any questions.
+ */
+
+/* @test
+ * @bug 6866804
+ * @summary Unit test for java.nio.file.Path
+ * @library ..
+ */
+
+import java.nio.ByteBuffer;
+import java.nio.file.*;
+import java.nio.file.attribute.*;
+import java.nio.channels.SeekableByteChannel;
+import java.security.Permission;
+import java.io.*;
+import java.util.*;
+
+/**
+ * Checks each method that accesses the file system does the right permission
+ * check when there is a security manager set.
+ */
+
+public class CheckPermissions {
+
+ static class Checks {
+ private List<Permission> permissionsChecked = new ArrayList<Permission>();
+ private Set<String> propertiesChecked = new HashSet<String>();
+ private List<String> readsChecked = new ArrayList<String>();
+ private List<String> writesChecked = new ArrayList<String>();
+ private List<String> deletesChecked = new ArrayList<String>();
+ private List<String> execsChecked = new ArrayList<String>();
+
+ List<Permission> permissionsChecked() { return permissionsChecked; }
+ Set<String> propertiesChecked() { return propertiesChecked; }
+ List<String> readsChecked() { return readsChecked; }
+ List<String> writesChecked() { return writesChecked; }
+ List<String> deletesChecked() { return deletesChecked; }
+ List<String> execsChecked() { return execsChecked; }
+ }
+
+ static ThreadLocal<Checks> myChecks =
+ new ThreadLocal<Checks>() {
+ @Override protected Checks initialValue() {
+ return null;
+ }
+ };
+
+ static void prepare() {
+ myChecks.set(new Checks());
+ }
+
+ static void assertCheckPermission(Class<? extends Permission> type,
+ String name)
+ {
+ for (Permission perm: myChecks.get().permissionsChecked()) {
+ if (type.isInstance(perm) && perm.getName().equals(name))
+ return;
+ }
+ throw new RuntimeException(type.getName() + "\"" + name + "\") not checked");
+ }
+
+ static void assertCheckPropertyAccess(String key) {
+ if (!myChecks.get().propertiesChecked().contains(key))
+ throw new RuntimeException("Property " + key + " not checked");
+ }
+
+ static void assertChecked(Path file, List<String> list) {
+ String s = file.toString();
+ for (String f: list) {
+ if (f.endsWith(s))
+ return;
+ }
+ throw new RuntimeException("Access not checked");
+ }
+
+ static void assertCheckRead(Path file) {
+ assertChecked(file, myChecks.get().readsChecked());
+ }
+
+ static void assertCheckWrite(Path file) {
+ assertChecked(file, myChecks.get().writesChecked());
+ }
+
+ static void assertCheckDelete(Path file) {
+ assertChecked(file, myChecks.get().deletesChecked());
+ }
+
+ static void assertCheckExec(Path file) {
+ assertChecked(file, myChecks.get().execsChecked());
+ }
+
+ static class LoggingSecurityManager extends SecurityManager {
+ static void install() {
+ System.setSecurityManager(new LoggingSecurityManager());
+ }
+
+ @Override
+ public void checkPermission(Permission perm) {
+ Checks checks = myChecks.get();
+ if (checks != null)
+ checks.permissionsChecked().add(perm);
+ }
+
+ @Override
+ public void checkPropertyAccess(String key) {
+ Checks checks = myChecks.get();
+ if (checks != null)
+ checks.propertiesChecked().add(key);
+ }
+
+ @Override
+ public void checkRead(String file) {
+ Checks checks = myChecks.get();
+ if (checks != null)
+ checks.readsChecked().add(file);
+ }
+
+ @Override
+ public void checkWrite(String file) {
+ Checks checks = myChecks.get();
+ if (checks != null)
+ checks.writesChecked().add(file);
+ }
+
+ @Override
+ public void checkDelete(String file) {
+ Checks checks = myChecks.get();
+ if (checks != null)
+ checks.deletesChecked().add(file);
+ }
+
+ @Override
+ public void checkExec(String file) {
+ Checks checks = myChecks.get();
+ if (checks != null)
+ checks.execsChecked().add(file);
+ }
+ }
+
+ static void testBasicFileAttributeView(BasicFileAttributeView view, Path file)
+ throws IOException
+ {
+ prepare();
+ view.readAttributes();
+ assertCheckRead(file);
+
+ prepare();
+ FileTime now = FileTime.fromMillis(System.currentTimeMillis());
+ view.setTimes(null, now, now);
+ assertCheckWrite(file);
+ }
+
+ static void testPosixFileAttributeView(PosixFileAttributeView view, Path file)
+ throws IOException
+ {
+ prepare();
+ PosixFileAttributes attrs = view.readAttributes();
+ assertCheckRead(file);
+ assertCheckPermission(RuntimePermission.class, "accessUserInformation");
+
+ prepare();
+ view.setPermissions(attrs.permissions());
+ assertCheckWrite(file);
+ assertCheckPermission(RuntimePermission.class, "accessUserInformation");
+
+ prepare();
+ view.setOwner(attrs.owner());
+ assertCheckWrite(file);
+ assertCheckPermission(RuntimePermission.class, "accessUserInformation");
+
+ prepare();
+ view.setOwner(attrs.owner());
+ assertCheckWrite(file);
+ assertCheckPermission(RuntimePermission.class, "accessUserInformation");
+ }
+
+ public static void main(String[] args) throws IOException {
+ Path dir = Paths.get(System.getProperty("test.src", "."));
+ Path file = dir.resolve("file1234").createFile();
+ try {
+ LoggingSecurityManager.install();
+
+ // -- checkAccess --
+
+ prepare();
+ file.checkAccess();
+ assertCheckRead(file);
+
+ prepare();
+ file.checkAccess(AccessMode.READ);
+ assertCheckRead(file);
+
+ prepare();
+ file.checkAccess(AccessMode.WRITE);
+ assertCheckWrite(file);
+
+ prepare();
+ try {
+ file.checkAccess(AccessMode.EXECUTE);
+ } catch (AccessDeniedException x) { }
+ assertCheckExec(file);
+
+ prepare();
+ try {
+ file.checkAccess(AccessMode.READ, AccessMode.WRITE, AccessMode.EXECUTE);
+ } catch (AccessDeniedException x) { }
+ assertCheckRead(file);
+ assertCheckWrite(file);
+ assertCheckExec(file);
+
+ // -- copyTo --
+
+ Path target = dir.resolve("target1234");
+ prepare();
+ file.copyTo(target);
+ try {
+ assertCheckRead(file);
+ assertCheckWrite(target);
+ } finally {
+ target.delete();
+ }
+
+ if (TestUtil.supportsLinks(dir)) {
+ Path link = dir.resolve("link1234").createSymbolicLink(file);
+ try {
+ prepare();
+ link.copyTo(target, LinkOption.NOFOLLOW_LINKS);
+ try {
+ assertCheckRead(link);
+ assertCheckWrite(target);
+ assertCheckPermission(LinkPermission.class, "symbolic");
+ } finally {
+ target.delete();
+ }
+ } finally {
+ link.delete();
+ }
+ }
+
+ // -- createDirectory --
+
+ Path subdir = dir.resolve("subdir1234");
+ prepare();
+ subdir.createDirectory();
+ try {
+ assertCheckWrite(subdir);
+ } finally {
+ subdir.delete();
+ }
+
+ // -- createFile --
+
+ Path fileToCreate = dir.resolve("file7890");
+ prepare();
+ try {
+ fileToCreate.createFile();
+ assertCheckWrite(fileToCreate);
+ } finally {
+ fileToCreate.delete();
+ }
+
+ // -- createSymbolicLink --
+
+ if (TestUtil.supportsLinks(dir)) {
+ prepare();
+ Path link = dir.resolve("link1234").createSymbolicLink(file);
+ try {
+ assertCheckWrite(link);
+ assertCheckPermission(LinkPermission.class, "symbolic");
+ } finally {
+ link.delete();
+ }
+ }
+
+ // -- delete/deleteIfExists --
+
+ Path fileToDelete = dir.resolve("file7890");
+
+ fileToDelete.createFile();
+ prepare();
+ fileToDelete.delete();
+ assertCheckDelete(fileToDelete);
+
+ fileToDelete.createFile();
+ prepare();
+ fileToDelete.deleteIfExists();
+ assertCheckDelete(fileToDelete);
+
+ // -- exists/notExists --
+
+ prepare();
+ file.exists();
+ assertCheckRead(file);
+
+ prepare();
+ file.notExists();
+ assertCheckRead(file);
+
+ // -- getFileStore --
+
+ prepare();
+ file.getFileStore();
+ assertCheckRead(file);
+ assertCheckPermission(RuntimePermission.class, "getFileStoreAttributes");
+
+ // -- isSameFile --
+
+ prepare();
+ file.isSameFile(dir);
+ assertCheckRead(file);
+ assertCheckRead(dir);
+
+ // -- moveTo --
+
+ Path target2 = dir.resolve("target1234");
+ prepare();
+ file.moveTo(target2);
+ try {
+ assertCheckWrite(file);
+ assertCheckWrite(target2);
+ } finally {
+ // restore file
+ target2.moveTo(file);
+ }
+
+ // -- newByteChannel --
+
+ SeekableByteChannel sbc;
+
+ prepare();
+ sbc = file.newByteChannel();
+ try {
+ assertCheckRead(file);
+ } finally {
+ sbc.close();
+ }
+ prepare();
+ sbc = file.newByteChannel(StandardOpenOption.WRITE);
+ try {
+ assertCheckWrite(file);
+ } finally {
+ sbc.close();
+ }
+ prepare();
+ sbc = file.newByteChannel(StandardOpenOption.READ, StandardOpenOption.WRITE);
+ try {
+ assertCheckRead(file);
+ assertCheckWrite(file);
+ } finally {
+ sbc.close();
+ }
+
+ prepare();
+ sbc = file.newByteChannel(StandardOpenOption.DELETE_ON_CLOSE);
+ try {
+ assertCheckRead(file);
+ assertCheckDelete(file);
+ } finally {
+ sbc.close();
+ }
+ file.createFile(); // restore file
+
+
+ // -- newInputStream/newOutptuStream --
+
+ prepare();
+ InputStream in = file.newInputStream();
+ try {
+ assertCheckRead(file);
+ } finally {
+ in.close();
+ }
+ prepare();
+ OutputStream out = file.newOutputStream();
+ try {
+ assertCheckWrite(file);
+ } finally {
+ out.close();
+ }
+
+ // -- newDirectoryStream --
+
+ prepare();
+ DirectoryStream<Path> stream = dir.newDirectoryStream();
+ try {
+ assertCheckRead(dir);
+
+ if (stream instanceof SecureDirectoryStream<?>) {
+ Path entry;
+ SecureDirectoryStream<Path> sds =
+ (SecureDirectoryStream<Path>)stream;
+
+ // newByteChannel
+ entry = file.getName();
+ prepare();
+ sbc = sds.newByteChannel(entry, EnumSet.of(StandardOpenOption.READ));
+ try {
+ assertCheckRead(file);
+ } finally {
+ sbc.close();
+ }
+ prepare();
+ sbc = sds.newByteChannel(entry, EnumSet.of(StandardOpenOption.WRITE));
+ try {
+ assertCheckWrite(file);
+ } finally {
+ sbc.close();
+ }
+
+ // deleteFile
+ entry = file.getName();
+ prepare();
+ sds.deleteFile(entry);
+ assertCheckDelete(file);
+ dir.resolve(entry).createFile(); // restore file
+
+ // deleteDirectory
+ entry = Paths.get("subdir1234");
+ dir.resolve(entry).createDirectory();
+ prepare();
+ sds.deleteDirectory(entry);
+ assertCheckDelete(dir.resolve(entry));
+
+ // move
+ entry = Paths.get("tempname1234");
+ prepare();
+ sds.move(file.getName(), sds, entry);
+ assertCheckWrite(file);
+ assertCheckWrite(dir.resolve(entry));
+ sds.move(entry, sds, file.getName()); // restore file
+
+ // newDirectoryStream
+ entry = Paths.get("subdir1234");
+ dir.resolve(entry).createDirectory();
+ try {
+ prepare();
+ sds.newDirectoryStream(entry).close();
+ assertCheckRead(dir.resolve(entry));
+ } finally {
+ dir.resolve(entry).delete();
+ }
+
+ // getFileAttributeView to access attributes of directory
+ testBasicFileAttributeView(sds
+ .getFileAttributeView(BasicFileAttributeView.class), dir);
+ testPosixFileAttributeView(sds
+ .getFileAttributeView(PosixFileAttributeView.class), dir);
+
+ // getFileAttributeView to access attributes of entry
+ entry = file.getName();
+ testBasicFileAttributeView(sds
+ .getFileAttributeView(entry, BasicFileAttributeView.class), file);
+ testPosixFileAttributeView(sds
+ .getFileAttributeView(entry, PosixFileAttributeView.class), file);
+
+ } else {
+ System.out.println("SecureDirectoryStream not tested");
+ }
+
+ } finally {
+ stream.close();
+ }
+
+ // -- toAbsolutePath --
+
+ prepare();
+ file.getName().toAbsolutePath();
+ assertCheckPropertyAccess("user.dir");
+
+ // -- toRealPath --
+
+ prepare();
+ file.toRealPath(true);
+ assertCheckRead(file);
+
+ prepare();
+ file.toRealPath(false);
+ assertCheckRead(file);
+
+ prepare();
+ Paths.get(".").toRealPath(true);
+ assertCheckPropertyAccess("user.dir");
+
+ prepare();
+ Paths.get(".").toRealPath(false);
+ assertCheckPropertyAccess("user.dir");
+
+ // -- register --
+
+ WatchService watcher = FileSystems.getDefault().newWatchService();
+ try {
+ prepare();
+ dir.register(watcher, StandardWatchEventKind.ENTRY_DELETE);
+ assertCheckRead(dir);
+ } finally {
+ watcher.close();
+ }
+
+ // -- getAttribute/setAttribute/readAttributes --
+
+ prepare();
+ file.getAttribute("size");
+ assertCheckRead(file);
+
+ prepare();
+ file.setAttribute("lastModifiedTime",
+ FileTime.fromMillis(System.currentTimeMillis()));
+ assertCheckWrite(file);
+
+ prepare();
+ file.readAttributes("*");
+ assertCheckRead(file);
+
+ // -- BasicFileAttributeView --
+ testBasicFileAttributeView(file
+ .getFileAttributeView(BasicFileAttributeView.class), file);
+
+ // -- PosixFileAttributeView --
+
+ {
+ PosixFileAttributeView view =
+ file.getFileAttributeView(PosixFileAttributeView.class);
+ if (view != null &&
+ file.getFileStore().supportsFileAttributeView(PosixFileAttributeView.class))
+ {
+ testPosixFileAttributeView(view, file);
+ } else {
+ System.out.println("PosixFileAttributeView not tested");
+ }
+ }
+
+ // -- DosFileAttributeView --
+
+ {
+ DosFileAttributeView view =
+ file.getFileAttributeView(DosFileAttributeView.class);
+ if (view != null &&
+ file.getFileStore().supportsFileAttributeView(DosFileAttributeView.class))
+ {
+ prepare();
+ view.readAttributes();
+ assertCheckRead(file);
+
+ prepare();
+ view.setArchive(false);
+ assertCheckWrite(file);
+
+ prepare();
+ view.setHidden(false);
+ assertCheckWrite(file);
+
+ prepare();
+ view.setReadOnly(false);
+ assertCheckWrite(file);
+
+ prepare();
+ view.setSystem(false);
+ assertCheckWrite(file);
+ } else {
+ System.out.println("DosFileAttributeView not tested");
+ }
+ }
+
+ // -- FileOwnerAttributeView --
+
+ {
+ FileOwnerAttributeView view =
+ file.getFileAttributeView(FileOwnerAttributeView.class);
+ if (view != null &&
+ file.getFileStore().supportsFileAttributeView(FileOwnerAttributeView.class))
+ {
+ prepare();
+ UserPrincipal owner = view.getOwner();
+ assertCheckRead(file);
+ assertCheckPermission(RuntimePermission.class, "accessUserInformation");
+
+ prepare();
+ view.setOwner(owner);
+ assertCheckWrite(file);
+ assertCheckPermission(RuntimePermission.class, "accessUserInformation");
+
+ } else {
+ System.out.println("FileOwnerAttributeView not tested");
+ }
+ }
+
+ // -- UserDefinedFileAttributeView --
+
+ {
+ UserDefinedFileAttributeView view =
+ file.getFileAttributeView(UserDefinedFileAttributeView.class);
+ if (view != null &&
+ file.getFileStore().supportsFileAttributeView(UserDefinedFileAttributeView.class))
+ {
+ prepare();
+ view.write("test", ByteBuffer.wrap(new byte[100]));
+ assertCheckWrite(file);
+ assertCheckPermission(RuntimePermission.class,
+ "accessUserDefinedAttributes");
+
+ prepare();
+ view.read("test", ByteBuffer.allocate(100));
+ assertCheckRead(file);
+ assertCheckPermission(RuntimePermission.class,
+ "accessUserDefinedAttributes");
+
+ prepare();
+ view.size("test");
+ assertCheckRead(file);
+ assertCheckPermission(RuntimePermission.class,
+ "accessUserDefinedAttributes");
+
+ prepare();
+ view.list();
+ assertCheckRead(file);
+ assertCheckPermission(RuntimePermission.class,
+ "accessUserDefinedAttributes");
+
+ prepare();
+ view.delete("test");
+ assertCheckWrite(file);
+ assertCheckPermission(RuntimePermission.class,
+ "accessUserDefinedAttributes");
+ } else {
+ System.out.println("UserDefinedFileAttributeView not tested");
+ }
+ }
+
+ // -- AclFileAttributeView --
+ {
+ AclFileAttributeView view =
+ file.getFileAttributeView(AclFileAttributeView.class);
+ if (view != null &&
+ file.getFileStore().supportsFileAttributeView(AclFileAttributeView.class))
+ {
+ prepare();
+ List<AclEntry> acl = view.getAcl();
+ assertCheckRead(file);
+ assertCheckPermission(RuntimePermission.class, "accessUserInformation");
+ prepare();
+ view.setAcl(acl);
+ assertCheckWrite(file);
+ assertCheckPermission(RuntimePermission.class, "accessUserInformation");
+ } else {
+ System.out.println("AclFileAttributeView not tested");
+ }
+ }
+
+ // -- UserPrincipalLookupService
+
+ UserPrincipalLookupService lookupService =
+ FileSystems.getDefault().getUserPrincipalLookupService();
+ UserPrincipal owner = Attributes.getOwner(file);
+
+ prepare();
+ lookupService.lookupPrincipalByName(owner.getName());
+ assertCheckPermission(RuntimePermission.class,
+ "lookupUserInformation");
+
+ try {
+ UserPrincipal group = Attributes.readPosixFileAttributes(file).group();
+ prepare();
+ lookupService.lookupPrincipalByGroupName(group.getName());
+ assertCheckPermission(RuntimePermission.class,
+ "lookupUserInformation");
+ } catch (UnsupportedOperationException ignore) {
+ System.out.println("lookupPrincipalByGroupName not tested");
+ }
+
+
+ } finally {
+ file.deleteIfExists();
+ }
+ }
+}
--- a/jdk/test/java/nio/file/Path/Misc.java Thu Aug 20 08:42:38 2009 +0100
+++ b/jdk/test/java/nio/file/Path/Misc.java Thu Aug 20 08:48:29 2009 +0100
@@ -22,7 +22,7 @@
*/
/* @test
- * @bug 4313887 6838333 6866804
+ * @bug 4313887 6838333 6867101
* @summary Unit test for java.nio.file.Path for miscellenous methods not
* covered by other tests
* @library ..