8344078: Remove security manager dependency in java.nio

Reviewed-by: alanb, rriggs
This commit is contained in:
Brian Burkhalter 2024-11-18 19:17:14 +00:00
parent 2649406323
commit 922b12f30c
67 changed files with 285 additions and 1480 deletions

View file

@ -31,8 +31,6 @@ import java.util.Iterator;
import java.util.ServiceLoader;
import java.util.ServiceConfigurationError;
import java.util.concurrent.*;
import java.security.AccessController;
import java.security.PrivilegedAction;
/**
* Service-provider class for asynchronous channels.
@ -62,20 +60,15 @@ public abstract class AsynchronousChannelProvider {
private static class ProviderHolder {
static final AsynchronousChannelProvider provider = load();
@SuppressWarnings("removal")
private static AsynchronousChannelProvider load() {
return AccessController
.doPrivileged(new PrivilegedAction<>() {
public AsynchronousChannelProvider run() {
AsynchronousChannelProvider p;
p = loadProviderFromProperty();
if (p != null)
return p;
p = loadProviderAsService();
if (p != null)
return p;
return sun.nio.ch.DefaultAsynchronousChannelProvider.create();
}});
AsynchronousChannelProvider p;
p = loadProviderFromProperty();
if (p != null)
return p;
p = loadProviderAsService();
if (p != null)
return p;
return sun.nio.ch.DefaultAsynchronousChannelProvider.create();
}
private static AsynchronousChannelProvider loadProviderFromProperty() {
@ -87,7 +80,7 @@ public abstract class AsynchronousChannelProvider {
Object tmp = Class.forName(cn, true,
ClassLoader.getSystemClassLoader()).newInstance();
return (AsynchronousChannelProvider)tmp;
} catch (ClassNotFoundException | SecurityException |
} catch (ClassNotFoundException |
InstantiationException | IllegalAccessException x) {
throw new ServiceConfigurationError(null, x);
}
@ -98,17 +91,7 @@ public abstract class AsynchronousChannelProvider {
ServiceLoader.load(AsynchronousChannelProvider.class,
ClassLoader.getSystemClassLoader());
Iterator<AsynchronousChannelProvider> i = sl.iterator();
for (;;) {
try {
return (i.hasNext()) ? i.next() : null;
} catch (ServiceConfigurationError sce) {
if (sce.getCause() instanceof SecurityException) {
// Ignore the security exception, try the next provider
continue;
}
throw sce;
}
}
return sl.findFirst().orElse(null);
}
}

View file

@ -33,8 +33,6 @@ import java.nio.channels.DatagramChannel;
import java.nio.channels.Pipe;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Iterator;
import java.util.Objects;
import java.util.ServiceLoader;
@ -81,17 +79,13 @@ public abstract class SelectorProvider {
private static class Holder {
static final SelectorProvider INSTANCE = provider();
@SuppressWarnings("removal")
static SelectorProvider provider() {
PrivilegedAction<SelectorProvider> pa = () -> {
SelectorProvider sp;
if ((sp = loadProviderFromProperty()) != null)
return sp;
if ((sp = loadProviderAsService()) != null)
return sp;
return sun.nio.ch.DefaultSelectorProvider.get();
};
return AccessController.doPrivileged(pa);
SelectorProvider sp;
if ((sp = loadProviderFromProperty()) != null)
return sp;
if ((sp = loadProviderAsService()) != null)
return sp;
return sun.nio.ch.DefaultSelectorProvider.get();
}
private static SelectorProvider loadProviderFromProperty() {
@ -105,8 +99,7 @@ public abstract class SelectorProvider {
NoSuchMethodException |
IllegalAccessException |
InvocationTargetException |
InstantiationException |
SecurityException x) {
InstantiationException x) {
throw new ServiceConfigurationError(null, x);
}
}
@ -116,17 +109,7 @@ public abstract class SelectorProvider {
ServiceLoader.load(SelectorProvider.class,
ClassLoader.getSystemClassLoader());
Iterator<SelectorProvider> i = sl.iterator();
for (;;) {
try {
return i.hasNext() ? i.next() : null;
} catch (ServiceConfigurationError sce) {
if (sce.getCause() instanceof SecurityException) {
// Ignore the security exception, try the next provider
continue;
}
throw sce;
}
}
return sl.findFirst().orElse(null);
}
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2000, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2000, 2024, 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
@ -34,15 +34,12 @@ import sun.nio.cs.ThreadLocalCoders;
import java.nio.ByteBuffer;
import java.nio.CharBuffer;
import java.nio.charset.spi.CharsetProvider;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.Locale;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.ServiceConfigurationError;
import java.util.ServiceLoader;
import java.util.Set;
import java.util.SortedMap;
@ -346,9 +343,7 @@ public abstract class Charset
cache1 = new Object[] { charsetName, cs };
}
// Creates an iterator that walks over the available providers, ignoring
// those whose lookup or instantiation causes a security exception to be
// thrown. Should be invoked with full privileges.
// Creates an iterator that walks over the available providers
//
private static Iterator<CharsetProvider> providers() {
return new Iterator<>() {
@ -360,17 +355,9 @@ public abstract class Charset
private boolean getNext() {
while (next == null) {
try {
if (!i.hasNext())
return false;
next = i.next();
} catch (ServiceConfigurationError sce) {
if (sce.getCause() instanceof SecurityException) {
// Ignore security exceptions
continue;
}
throw sce;
}
if (!i.hasNext())
return false;
next = i.next();
}
return true;
}
@ -406,7 +393,6 @@ public abstract class Charset
ThreadTrackHolder.TRACKER.end(key);
}
@SuppressWarnings("removal")
private static Charset lookupViaProviders(final String charsetName) {
// The runtime startup sequence looks up standard charsets as a
@ -426,20 +412,13 @@ public abstract class Charset
return null;
}
try {
return AccessController.doPrivileged(
new PrivilegedAction<>() {
public Charset run() {
for (Iterator<CharsetProvider> i = providers();
i.hasNext();) {
CharsetProvider cp = i.next();
Charset cs = cp.charsetForName(charsetName);
if (cs != null)
return cs;
}
return null;
}
});
for (Iterator<CharsetProvider> i = providers(); i.hasNext();) {
CharsetProvider cp = i.next();
Charset cs = cp.charsetForName(charsetName);
if (cs != null)
return cs;
}
return null;
} finally {
endLookup(key);
}
@ -449,22 +428,18 @@ public abstract class Charset
private static class ExtendedProviderHolder {
static final CharsetProvider[] extendedProviders = extendedProviders();
// returns ExtendedProvider, if installed
@SuppressWarnings("removal")
private static CharsetProvider[] extendedProviders() {
return AccessController.doPrivileged(new PrivilegedAction<>() {
public CharsetProvider[] run() {
CharsetProvider[] cps = new CharsetProvider[1];
int n = 0;
ServiceLoader<CharsetProvider> sl =
ServiceLoader.loadInstalled(CharsetProvider.class);
for (CharsetProvider cp : sl) {
if (n + 1 > cps.length) {
cps = Arrays.copyOf(cps, cps.length << 1);
}
cps[n++] = cp;
}
return n == cps.length ? cps : Arrays.copyOf(cps, n);
}});
CharsetProvider[] cps = new CharsetProvider[1];
int n = 0;
ServiceLoader<CharsetProvider> sl =
ServiceLoader.loadInstalled(CharsetProvider.class);
for (CharsetProvider cp : sl) {
if (n + 1 > cps.length) {
cps = Arrays.copyOf(cps, cps.length << 1);
}
cps[n++] = cp;
}
return n == cps.length ? cps : Arrays.copyOf(cps, n);
}
}
@ -628,26 +603,20 @@ public abstract class Charset
* @return An immutable, case-insensitive map from canonical charset names
* to charset objects
*/
@SuppressWarnings("removal")
public static SortedMap<String,Charset> availableCharsets() {
return AccessController.doPrivileged(
new PrivilegedAction<>() {
public SortedMap<String,Charset> run() {
TreeMap<String,Charset> m =
new TreeMap<>(
String.CASE_INSENSITIVE_ORDER);
put(standardProvider.charsets(), m);
CharsetProvider[] ecps = ExtendedProviderHolder.extendedProviders;
for (CharsetProvider ecp :ecps) {
put(ecp.charsets(), m);
}
for (Iterator<CharsetProvider> i = providers(); i.hasNext();) {
CharsetProvider cp = i.next();
put(cp.charsets(), m);
}
return Collections.unmodifiableSortedMap(m);
}
});
TreeMap<String,Charset> m =
new TreeMap<>(
String.CASE_INSENSITIVE_ORDER);
put(standardProvider.charsets(), m);
CharsetProvider[] ecps = ExtendedProviderHolder.extendedProviders;
for (CharsetProvider ecp :ecps) {
put(ecp.charsets(), m);
}
for (Iterator<CharsetProvider> i = providers(); i.hasNext();) {
CharsetProvider cp = i.next();
put(cp.charsets(), m);
}
return Collections.unmodifiableSortedMap(m);
}
private @Stable static Charset defaultCharset;

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2011, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2011, 2024, 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
@ -116,13 +116,9 @@ class CopyMoveHelper {
// attributes of source file
BasicFileAttributes sourceAttrs = null;
if (sourcePosixView != null) {
try {
sourceAttrs = Files.readAttributes(source,
PosixFileAttributes.class,
linkOptions);
} catch (SecurityException ignored) {
// okay to continue if RuntimePermission("accessUserInformation") not granted
}
sourceAttrs = Files.readAttributes(source,
PosixFileAttributes.class,
linkOptions);
}
if (sourceAttrs == null)
sourceAttrs = Files.readAttributes(source,
@ -173,11 +169,7 @@ class CopyMoveHelper {
if (sourceAttrs instanceof PosixFileAttributes sourcePosixAttrs &&
targetView instanceof PosixFileAttributeView targetPosixView) {
try {
targetPosixView.setPermissions(sourcePosixAttrs.permissions());
} catch (SecurityException ignored) {
// okay to continue if RuntimePermission("accessUserInformation") not granted
}
targetPosixView.setPermissions(sourcePosixAttrs.permissions());
}
} catch (Throwable x) {
// rollback

View file

@ -25,12 +25,10 @@
package java.nio.file;
import java.nio.file.spi.FileSystemProvider;
import java.net.URI;
import java.io.IOException;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.lang.reflect.Constructor;
import java.net.URI;
import java.nio.file.spi.FileSystemProvider;
import java.util.Collections;
import java.util.Map;
import java.util.ServiceConfigurationError;
@ -96,13 +94,7 @@ public final class FileSystems {
// returns default file system
private static FileSystem defaultFileSystem() {
// load default provider
@SuppressWarnings("removal")
FileSystemProvider provider = AccessController
.doPrivileged(new PrivilegedAction<>() {
public FileSystemProvider run() {
return getDefaultProvider();
}
});
FileSystemProvider provider = getDefaultProvider();
// return file system
return provider.getFileSystem(URI.create("file:///"));

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2013, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2014, 2023, 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
@ -58,8 +58,6 @@ class FileTreeIterator implements Iterator<Event>, Closeable {
* if {@code maxDepth} is negative
* @throws IOException
* if an I/O errors occurs opening the starting file
* @throws SecurityException
* if the security manager denies access to the starting file
* @throws NullPointerException
* if {@code start} or {@code options} is {@code null} or
* the options array contains a {@code null} element

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2007, 2023, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2007, 2024, 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
@ -198,16 +198,12 @@ class FileTreeWalker implements Closeable {
* the walk is following sym links is not. The {@code canUseCached}
* argument determines whether this method can use cached attributes.
*/
@SuppressWarnings("removal")
private BasicFileAttributes getAttributes(Path file, boolean canUseCached)
throws IOException
{
// if attributes are cached then use them if possible
if (canUseCached &&
(file instanceof BasicFileAttributesHolder) &&
(System.getSecurityManager() == null))
{
BasicFileAttributes cached = ((BasicFileAttributesHolder)file).get();
if (canUseCached && (file instanceof BasicFileAttributesHolder bfah)) {
BasicFileAttributes cached = bfah.get();
if (cached != null && (!followLinks || !cached.isSymbolicLink())) {
return cached;
}
@ -250,7 +246,7 @@ class FileTreeWalker implements Closeable {
// cycle detected
return true;
}
} catch (IOException | SecurityException x) {
} catch (IOException e) {
// ignore
}
}
@ -262,25 +258,16 @@ class FileTreeWalker implements Closeable {
* Visits the given file, returning the {@code Event} corresponding to that
* visit.
*
* The {@code ignoreSecurityException} parameter determines whether
* any SecurityException should be ignored or not. If a SecurityException
* is thrown, and is ignored, then this method returns {@code null} to
* mean that there is no event corresponding to a visit to the file.
*
* The {@code canUseCached} parameter determines whether cached attributes
* for the file can be used or not.
*/
private Event visit(Path entry, boolean ignoreSecurityException, boolean canUseCached) {
private Event visit(Path entry, boolean canUseCached) {
// need the file attributes
BasicFileAttributes attrs;
try {
attrs = getAttributes(entry, canUseCached);
} catch (IOException ioe) {
return new Event(EventType.ENTRY, entry, ioe);
} catch (SecurityException se) {
if (ignoreSecurityException)
return null;
throw se;
}
// at maximum depth or file is not a directory
@ -301,10 +288,6 @@ class FileTreeWalker implements Closeable {
stream = Files.newDirectoryStream(entry);
} catch (IOException ioe) {
return new Event(EventType.ENTRY, entry, ioe);
} catch (SecurityException se) {
if (ignoreSecurityException)
return null;
throw se;
}
// push a directory node to the stack and return an event
@ -321,7 +304,6 @@ class FileTreeWalker implements Closeable {
throw new IllegalStateException("Closed");
Event ev = visit(file,
false, // ignoreSecurityException
false); // canUseCached
assert ev != null;
return ev;
@ -372,7 +354,6 @@ class FileTreeWalker implements Closeable {
// visit the entry
ev = visit(entry,
true, // ignoreSecurityException
true); // canUseCached
} while (ev == null);

View file

@ -58,8 +58,6 @@ import java.nio.file.attribute.PosixFilePermission;
import java.nio.file.attribute.UserPrincipal;
import java.nio.file.spi.FileSystemProvider;
import java.nio.file.spi.FileTypeDetector;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@ -696,14 +694,8 @@ public final class Files {
} catch (IOException x) {
// parent may not exist or other reason
}
SecurityException se = null;
Path absDir = dir;
try {
absDir = dir.toAbsolutePath();
} catch (SecurityException x) {
// don't have permission to get absolute path
se = x;
}
Path absDir = dir.toAbsolutePath();
// find a descendant that exists
Path parent = absDir.getParent();
while (parent != null) {
@ -717,12 +709,8 @@ public final class Files {
}
if (parent == null) {
// unable to find existing parent
if (se == null) {
throw new FileSystemException(absDir.toString(), null,
"Unable to determine if root directory exists");
} else {
throw se;
}
throw new FileSystemException(absDir.toString(), null,
"Unable to determine if root directory exists");
}
// create directories
@ -1525,29 +1513,19 @@ public final class Files {
loadInstalledDetectors();
// creates the default file type detector
@SuppressWarnings("removal")
private static FileTypeDetector createDefaultFileTypeDetector() {
return AccessController
.doPrivileged(new PrivilegedAction<>() {
@Override public FileTypeDetector run() {
return sun.nio.fs.DefaultFileTypeDetector.create();
}});
return sun.nio.fs.DefaultFileTypeDetector.create();
}
// loads all installed file type detectors
@SuppressWarnings("removal")
private static List<FileTypeDetector> loadInstalledDetectors() {
return AccessController
.doPrivileged(new PrivilegedAction<>() {
@Override public List<FileTypeDetector> run() {
List<FileTypeDetector> list = new ArrayList<>();
ServiceLoader<FileTypeDetector> loader = ServiceLoader
.load(FileTypeDetector.class, ClassLoader.getSystemClassLoader());
for (FileTypeDetector detector: loader) {
list.add(detector);
}
return list;
}});
List<FileTypeDetector> list = new ArrayList<>();
ServiceLoader<FileTypeDetector> loader = ServiceLoader
.load(FileTypeDetector.class, ClassLoader.getSystemClassLoader());
for (FileTypeDetector detector: loader) {
list.add(detector);
}
return list;
}
}
@ -2863,26 +2841,16 @@ public final class Files {
}
// attempt to delete an existing file
SecurityException se = null;
if (replaceExisting) {
try {
deleteIfExists(target);
} catch (SecurityException x) {
se = x;
}
deleteIfExists(target);
}
// attempt to create target file. If it fails with
// FileAlreadyExistsException then it may be because the security
// manager prevented us from deleting the file, in which case we just
// throw the SecurityException.
// attempt to create target file.
OutputStream ostream;
try {
ostream = newOutputStream(target, StandardOpenOption.CREATE_NEW,
StandardOpenOption.WRITE);
} catch (FileAlreadyExistsException x) {
if (se != null)
throw se;
// someone else won the race and created the file
throw x;
}

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 2009, 2021, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2009, 2024, 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
@ -117,16 +117,12 @@ class TempFileHelper {
}
// loop generating random names until file or directory can be created
@SuppressWarnings("removal")
SecurityManager sm = System.getSecurityManager();
for (;;) {
Path f;
try {
f = generatePath(prefix, suffix, dir);
} catch (InvalidPathException e) {
// don't reveal temporary directory location
if (sm != null)
throw new IllegalArgumentException("Invalid prefix or suffix");
throw e;
}
try {
@ -135,11 +131,6 @@ class TempFileHelper {
} else {
return Files.createFile(f, attrs);
}
} catch (SecurityException e) {
// don't reveal temporary directory location
if (dir == tmpdir && sm != null)
throw new SecurityException("Unable to create temporary file or directory");
throw e;
} catch (FileAlreadyExistsException e) {
// ignore
}

View file

@ -45,7 +45,6 @@ import java.nio.file.FileSystemNotFoundException;
import java.nio.file.FileSystems;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.LinkPermission;
import java.nio.file.NoSuchFileException;
import java.nio.file.NotDirectoryException;
import java.nio.file.NotLinkException;
@ -68,8 +67,6 @@ import java.util.ServiceConfigurationError;
import java.util.ServiceLoader;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.security.AccessController;
import java.security.PrivilegedAction;
import sun.nio.ch.FileChannelImpl;
@ -185,13 +182,7 @@ public abstract class FileSystemProvider {
}
loadingProviders = true;
@SuppressWarnings("removal")
List<FileSystemProvider> list = AccessController
.doPrivileged(new PrivilegedAction<>() {
@Override
public List<FileSystemProvider> run() {
return loadInstalledProviders();
}});
List<FileSystemProvider> list = loadInstalledProviders();
// insert the default provider at the start of the list
list.add(0, defaultProvider);