8344337: SecurityManager cleanup in java.prefs module
Reviewed-by: lancea, bpb, rriggs, iris
This commit is contained in:
parent
1c7f34d3dd
commit
4d4cef800a
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 2012, 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
|
||||
@ -28,8 +28,6 @@ package java.util.prefs;
|
||||
import java.util.Objects;
|
||||
|
||||
class MacOSXPreferences extends AbstractPreferences {
|
||||
// fixme need security checks?
|
||||
|
||||
// CF preferences file name for Java nodes with short names
|
||||
// This value is also in MacOSXPreferencesFile.c
|
||||
private static final String defaultAppName = "com.apple.java.util.prefs";
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011, 2021, 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
|
||||
@ -82,15 +82,9 @@ class MacOSXPreferencesFile {
|
||||
loadPrefsLib();
|
||||
}
|
||||
|
||||
@SuppressWarnings({"removal", "restricted"})
|
||||
@SuppressWarnings("restricted")
|
||||
private static void loadPrefsLib() {
|
||||
java.security.AccessController.doPrivileged(
|
||||
new java.security.PrivilegedAction<Void>() {
|
||||
public Void run() {
|
||||
System.loadLibrary("prefs");
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static class FlushTask extends TimerTask {
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2022, 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
|
||||
@ -27,8 +27,6 @@ package java.util.prefs;
|
||||
|
||||
import java.util.*;
|
||||
import java.io.*;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
|
||||
/**
|
||||
* This class provides a skeletal implementation of the {@link Preferences}
|
||||
@ -1058,15 +1056,9 @@ public abstract class AbstractPreferences extends Preferences {
|
||||
* preference tree, {@code false} if it's in the system
|
||||
* preference tree.
|
||||
*/
|
||||
@SuppressWarnings("removal")
|
||||
public boolean isUserNode() {
|
||||
return AccessController.doPrivileged(
|
||||
new PrivilegedAction<Boolean>() {
|
||||
public Boolean run() {
|
||||
return root == Preferences.userRoot();
|
||||
}
|
||||
}).booleanValue();
|
||||
}
|
||||
|
||||
public void addPreferenceChangeListener(PreferenceChangeListener pcl) {
|
||||
if (pcl==null)
|
||||
|
@ -30,20 +30,10 @@ import jdk.internal.util.OperatingSystem;
|
||||
import java.io.InputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.security.AccessController;
|
||||
import java.security.Permission;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.util.Iterator;
|
||||
import java.util.ServiceLoader;
|
||||
import java.util.ServiceConfigurationError;
|
||||
|
||||
// These imports needed only as a workaround for a JavaDoc bug
|
||||
import java.lang.RuntimePermission;
|
||||
import java.lang.Integer;
|
||||
import java.lang.Long;
|
||||
import java.lang.Float;
|
||||
import java.lang.Double;
|
||||
|
||||
/**
|
||||
* A node in a hierarchical collection of preference data. This class
|
||||
* allows applications to store and retrieve user and system
|
||||
@ -227,19 +217,10 @@ public abstract class Preferences {
|
||||
|
||||
private static final PreferencesFactory factory = factory();
|
||||
|
||||
@SuppressWarnings("removal")
|
||||
private static PreferencesFactory factory() {
|
||||
// 1. Try user-specified system property
|
||||
String factoryName = AccessController.doPrivileged(
|
||||
new PrivilegedAction<String>() {
|
||||
public String run() {
|
||||
return System.getProperty(
|
||||
"java.util.prefs.PreferencesFactory");}});
|
||||
String factoryName = System.getProperty("java.util.prefs.PreferencesFactory");
|
||||
if (factoryName != null) {
|
||||
// FIXME: This code should be run in a doPrivileged and
|
||||
// not use the context classloader, to avoid being
|
||||
// dependent on the invoking thread.
|
||||
// Checking AllPermission also seems wrong.
|
||||
try {
|
||||
@SuppressWarnings("deprecation")
|
||||
Object result =Class.forName(factoryName, false,
|
||||
@ -250,10 +231,6 @@ public abstract class Preferences {
|
||||
try {
|
||||
// workaround for javaws, plugin,
|
||||
// load factory class using non-system classloader
|
||||
SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) {
|
||||
sm.checkPermission(new java.security.AllPermission());
|
||||
}
|
||||
@SuppressWarnings("deprecation")
|
||||
Object result = Class.forName(factoryName, false,
|
||||
Thread.currentThread()
|
||||
@ -267,14 +244,6 @@ public abstract class Preferences {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return AccessController.doPrivileged(
|
||||
new PrivilegedAction<PreferencesFactory>() {
|
||||
public PreferencesFactory run() {
|
||||
return factory1();}});
|
||||
}
|
||||
|
||||
private static PreferencesFactory factory1() {
|
||||
// 2. Try service provider interface
|
||||
Iterator<PreferencesFactory> itr = ServiceLoader
|
||||
.load(PreferencesFactory.class, ClassLoader.getSystemClassLoader())
|
||||
@ -427,24 +396,12 @@ public abstract class Preferences {
|
||||
return "/" + packageName.replace('.', '/');
|
||||
}
|
||||
|
||||
/**
|
||||
* This permission object represents the permission required to get
|
||||
* access to the user or system root (which in turn allows for all
|
||||
* other operations).
|
||||
*/
|
||||
private static Permission prefsPerm = new RuntimePermission("preferences");
|
||||
|
||||
/**
|
||||
* Returns the root preference node for the calling user.
|
||||
*
|
||||
* @return the root preference node for the calling user.
|
||||
*/
|
||||
public static Preferences userRoot() {
|
||||
@SuppressWarnings("removal")
|
||||
SecurityManager security = System.getSecurityManager();
|
||||
if (security != null)
|
||||
security.checkPermission(prefsPerm);
|
||||
|
||||
return factory.userRoot();
|
||||
}
|
||||
|
||||
@ -454,11 +411,6 @@ public abstract class Preferences {
|
||||
* @return the root preference node for the system.
|
||||
*/
|
||||
public static Preferences systemRoot() {
|
||||
@SuppressWarnings("removal")
|
||||
SecurityManager security = System.getSecurityManager();
|
||||
if (security != null)
|
||||
security.checkPermission(prefsPerm);
|
||||
|
||||
return factory.systemRoot();
|
||||
}
|
||||
|
||||
|
@ -27,9 +27,6 @@ package java.util.prefs;
|
||||
|
||||
import java.util.*;
|
||||
import java.io.*;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.security.PrivilegedExceptionAction;
|
||||
import java.security.PrivilegedActionException;
|
||||
import sun.util.logging.PlatformLogger;
|
||||
|
||||
@ -53,13 +50,9 @@ class FileSystemPreferences extends AbstractPreferences {
|
||||
loadPrefsLib();
|
||||
}
|
||||
|
||||
@SuppressWarnings({"removal", "restricted"})
|
||||
@SuppressWarnings("restricted")
|
||||
private static void loadPrefsLib() {
|
||||
PrivilegedAction<Void> load = () -> {
|
||||
System.loadLibrary("prefs");
|
||||
return null;
|
||||
};
|
||||
AccessController.doPrivileged(load);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -67,8 +60,7 @@ class FileSystemPreferences extends AbstractPreferences {
|
||||
*/
|
||||
@SuppressWarnings("removal")
|
||||
private static final int SYNC_INTERVAL = Math.max(1,
|
||||
AccessController.doPrivileged((PrivilegedAction<Integer>) () ->
|
||||
Integer.getInteger("java.util.prefs.syncInterval", 30)));
|
||||
Integer.getInteger("java.util.prefs.syncInterval", 30));
|
||||
|
||||
/**
|
||||
* Returns logger for error messages. Backing store exceptions are logged at
|
||||
@ -117,10 +109,7 @@ class FileSystemPreferences extends AbstractPreferences {
|
||||
return root;
|
||||
}
|
||||
|
||||
@SuppressWarnings("removal")
|
||||
private static void setupUserRoot() {
|
||||
AccessController.doPrivileged(new PrivilegedAction<Void>() {
|
||||
public Void run() {
|
||||
userRootDir =
|
||||
new File(System.getProperty("java.util.prefs.userRoot",
|
||||
System.getProperty("user.home")), ".java/.userPrefs");
|
||||
@ -134,17 +123,17 @@ class FileSystemPreferences extends AbstractPreferences {
|
||||
" on userRoot directory. ");
|
||||
}
|
||||
getLogger().info("Created user preferences directory.");
|
||||
}
|
||||
else
|
||||
} else {
|
||||
getLogger().warning("Couldn't create user preferences" +
|
||||
" directory. User preferences are unusable.");
|
||||
}
|
||||
}
|
||||
isUserRootWritable = userRootDir.canWrite();
|
||||
String USER_NAME = System.getProperty("user.name");
|
||||
userLockFile = new File(userRootDir,".user.lock." + USER_NAME);
|
||||
userRootModFile = new File (userRootDir,
|
||||
".userRootModFile." + USER_NAME);
|
||||
if (!userRootModFile.exists())
|
||||
if (!userRootModFile.exists()) {
|
||||
try {
|
||||
// create if does not exist.
|
||||
userRootModFile.createNewFile();
|
||||
@ -159,10 +148,8 @@ class FileSystemPreferences extends AbstractPreferences {
|
||||
} catch (IOException e) {
|
||||
getLogger().warning(e.toString());
|
||||
}
|
||||
userRootModTime = userRootModFile.lastModified();
|
||||
return null;
|
||||
}
|
||||
});
|
||||
userRootModTime = userRootModFile.lastModified();
|
||||
}
|
||||
|
||||
|
||||
@ -185,10 +172,7 @@ class FileSystemPreferences extends AbstractPreferences {
|
||||
return root;
|
||||
}
|
||||
|
||||
@SuppressWarnings("removal")
|
||||
private static void setupSystemRoot() {
|
||||
AccessController.doPrivileged(new PrivilegedAction<Void>() {
|
||||
public Void run() {
|
||||
String systemPrefsDirName =
|
||||
System.getProperty("java.util.prefs.systemRoot", "/etc/.java");
|
||||
systemRootDir =
|
||||
@ -219,24 +203,23 @@ class FileSystemPreferences extends AbstractPreferences {
|
||||
}
|
||||
isSystemRootWritable = systemRootDir.canWrite();
|
||||
systemLockFile = new File(systemRootDir, ".system.lock");
|
||||
systemRootModFile =
|
||||
new File (systemRootDir,".systemRootModFile");
|
||||
if (!systemRootModFile.exists() && isSystemRootWritable)
|
||||
systemRootModFile = new File (systemRootDir, ".systemRootModFile");
|
||||
if (!systemRootModFile.exists() && isSystemRootWritable) {
|
||||
try {
|
||||
// create if does not exist.
|
||||
systemRootModFile.createNewFile();
|
||||
int result = chmod(systemRootModFile.getCanonicalPath(),
|
||||
USER_RW_ALL_READ);
|
||||
if (result !=0)
|
||||
if (result != 0) {
|
||||
getLogger().warning("Chmod failed on " +
|
||||
systemRootModFile.getCanonicalPath() +
|
||||
" Unix error code " + result);
|
||||
} catch (IOException e) { getLogger().warning(e.toString());
|
||||
}
|
||||
} catch (IOException e) {
|
||||
getLogger().warning(e.toString());
|
||||
}
|
||||
}
|
||||
systemRootModTime = systemRootModFile.lastModified();
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -456,7 +439,6 @@ class FileSystemPreferences extends AbstractPreferences {
|
||||
addShutdownHook();
|
||||
}
|
||||
|
||||
@SuppressWarnings("removal")
|
||||
private static void addShutdownHook() {
|
||||
// Add periodic timer task to periodically sync cached prefs
|
||||
syncTimer.schedule(new TimerTask() {
|
||||
@ -466,8 +448,6 @@ class FileSystemPreferences extends AbstractPreferences {
|
||||
}, SYNC_INTERVAL*1000, SYNC_INTERVAL*1000);
|
||||
|
||||
// Add shutdown hook to flush cached prefs on normal termination
|
||||
AccessController.doPrivileged(new PrivilegedAction<Void>() {
|
||||
public Void run() {
|
||||
Runtime.getRuntime().addShutdownHook(
|
||||
new Thread(null, null, "Sync Timer Thread", 0, false) {
|
||||
public void run() {
|
||||
@ -475,9 +455,6 @@ class FileSystemPreferences extends AbstractPreferences {
|
||||
syncWorld();
|
||||
}
|
||||
});
|
||||
return null;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static void syncWorld() {
|
||||
@ -526,19 +503,13 @@ class FileSystemPreferences extends AbstractPreferences {
|
||||
* parent node and name. This constructor, called from childSpi,
|
||||
* is used to make every node except for the two //roots.
|
||||
*/
|
||||
@SuppressWarnings("removal")
|
||||
private FileSystemPreferences(FileSystemPreferences parent, String name) {
|
||||
super(parent, name);
|
||||
isUserNode = parent.isUserNode;
|
||||
dir = new File(parent.dir, dirName(name));
|
||||
prefsFile = new File(dir, "prefs.xml");
|
||||
tmpFile = new File(dir, "prefs.tmp");
|
||||
AccessController.doPrivileged(new PrivilegedAction<Void>() {
|
||||
public Void run() {
|
||||
newNode = !dir.exists();
|
||||
return null;
|
||||
}
|
||||
});
|
||||
if (newNode) {
|
||||
// These 2 things guarantee node will get written at next flush/sync
|
||||
prefsCache = new TreeMap<>();
|
||||
@ -596,12 +567,7 @@ class FileSystemPreferences extends AbstractPreferences {
|
||||
* fails, a BackingStoreException is thrown and both prefsCache and
|
||||
* lastSyncTime are unaffected by the call.
|
||||
*/
|
||||
@SuppressWarnings("removal")
|
||||
private void loadCache() throws BackingStoreException {
|
||||
try {
|
||||
AccessController.doPrivileged(
|
||||
new PrivilegedExceptionAction<Void>() {
|
||||
public Void run() throws BackingStoreException {
|
||||
Map<String, String> m = new TreeMap<>();
|
||||
long newLastSyncTime = 0;
|
||||
try {
|
||||
@ -627,12 +593,6 @@ class FileSystemPreferences extends AbstractPreferences {
|
||||
// Attempt succeeded; update state
|
||||
prefsCache = m;
|
||||
lastSyncTime = newLastSyncTime;
|
||||
return null;
|
||||
}
|
||||
});
|
||||
} catch (PrivilegedActionException e) {
|
||||
throw (BackingStoreException) e.getException();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -644,12 +604,7 @@ class FileSystemPreferences extends AbstractPreferences {
|
||||
* and lastSyncTime will be unaffected by this call. This call will
|
||||
* NEVER leave prefsFile in a corrupt state.
|
||||
*/
|
||||
@SuppressWarnings("removal")
|
||||
private void writeBackCache() throws BackingStoreException {
|
||||
try {
|
||||
AccessController.doPrivileged(
|
||||
new PrivilegedExceptionAction<Void>() {
|
||||
public Void run() throws BackingStoreException {
|
||||
try {
|
||||
if (!dir.exists() && !dir.mkdirs())
|
||||
throw new BackingStoreException(dir +
|
||||
@ -660,17 +615,11 @@ class FileSystemPreferences extends AbstractPreferences {
|
||||
if (!tmpFile.renameTo(prefsFile))
|
||||
throw new BackingStoreException("Can't rename " +
|
||||
tmpFile + " to " + prefsFile);
|
||||
} catch(BackingStoreException e) {
|
||||
throw e;
|
||||
} catch(Exception e) {
|
||||
if (e instanceof BackingStoreException)
|
||||
throw (BackingStoreException)e;
|
||||
throw new BackingStoreException(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
} catch (PrivilegedActionException e) {
|
||||
throw (BackingStoreException) e.getException();
|
||||
}
|
||||
}
|
||||
|
||||
protected String[] keysSpi() {
|
||||
@ -678,11 +627,7 @@ class FileSystemPreferences extends AbstractPreferences {
|
||||
return prefsCache.keySet().toArray(new String[prefsCache.size()]);
|
||||
}
|
||||
|
||||
@SuppressWarnings("removal")
|
||||
protected String[] childrenNamesSpi() {
|
||||
return AccessController.doPrivileged(
|
||||
new PrivilegedAction<String[]>() {
|
||||
public String[] run() {
|
||||
List<String> result = new ArrayList<>();
|
||||
File[] dirContents = dir.listFiles();
|
||||
if (dirContents != null) {
|
||||
@ -692,8 +637,6 @@ class FileSystemPreferences extends AbstractPreferences {
|
||||
}
|
||||
return result.toArray(EMPTY_STRING_ARRAY);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static final String[] EMPTY_STRING_ARRAY = new String[0];
|
||||
|
||||
@ -717,19 +660,14 @@ class FileSystemPreferences extends AbstractPreferences {
|
||||
/**
|
||||
* Called with file lock held (in addition to node locks).
|
||||
*/
|
||||
@SuppressWarnings("removal")
|
||||
protected void removeNodeSpi() throws BackingStoreException {
|
||||
try {
|
||||
AccessController.doPrivileged(
|
||||
new PrivilegedExceptionAction<Void>() {
|
||||
public Void run() throws BackingStoreException {
|
||||
if (changeLog.contains(nodeCreate)) {
|
||||
changeLog.remove(nodeCreate);
|
||||
nodeCreate = null;
|
||||
return null;
|
||||
return;
|
||||
}
|
||||
if (!dir.exists())
|
||||
return null;
|
||||
return;
|
||||
prefsFile.delete();
|
||||
tmpFile.delete();
|
||||
// dir should be empty now. If it's not, empty it
|
||||
@ -744,15 +682,8 @@ class FileSystemPreferences extends AbstractPreferences {
|
||||
if (!dir.delete())
|
||||
throw new BackingStoreException("Couldn't delete dir: "
|
||||
+ dir);
|
||||
return null;
|
||||
}
|
||||
});
|
||||
} catch (PrivilegedActionException e) {
|
||||
throw (BackingStoreException) e.getException();
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("removal")
|
||||
public synchronized void sync() throws BackingStoreException {
|
||||
boolean userNode = isUserNode();
|
||||
boolean shared;
|
||||
@ -765,12 +696,9 @@ class FileSystemPreferences extends AbstractPreferences {
|
||||
shared = !isSystemRootWritable;
|
||||
}
|
||||
synchronized (isUserNode()? userLockFile:systemLockFile) {
|
||||
if (!lockFile(shared))
|
||||
if (!lockFile(shared)) {
|
||||
throw (new BackingStoreException("Couldn't get file lock."));
|
||||
final Long newModTime =
|
||||
AccessController.doPrivileged(
|
||||
new PrivilegedAction<Long>() {
|
||||
public Long run() {
|
||||
}
|
||||
long nmt;
|
||||
if (isUserNode()) {
|
||||
nmt = userRootModFile.lastModified();
|
||||
@ -779,44 +707,23 @@ class FileSystemPreferences extends AbstractPreferences {
|
||||
nmt = systemRootModFile.lastModified();
|
||||
isSystemRootModified = systemRootModTime == nmt;
|
||||
}
|
||||
return nmt;
|
||||
}
|
||||
});
|
||||
final long newModTime = nmt;
|
||||
try {
|
||||
super.sync();
|
||||
AccessController.doPrivileged(new PrivilegedAction<Void>() {
|
||||
public Void run() {
|
||||
if (isUserNode()) {
|
||||
userRootModTime = newModTime.longValue() + 1000;
|
||||
userRootModTime = newModTime + 1000;
|
||||
userRootModFile.setLastModified(userRootModTime);
|
||||
} else {
|
||||
systemRootModTime = newModTime.longValue() + 1000;
|
||||
systemRootModTime = newModTime + 1000;
|
||||
systemRootModFile.setLastModified(systemRootModTime);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
} finally {
|
||||
unlockFile();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("removal")
|
||||
protected void syncSpi() throws BackingStoreException {
|
||||
try {
|
||||
AccessController.doPrivileged(
|
||||
new PrivilegedExceptionAction<Void>() {
|
||||
public Void run() throws BackingStoreException {
|
||||
syncSpiPrivileged();
|
||||
return null;
|
||||
}
|
||||
});
|
||||
} catch (PrivilegedActionException e) {
|
||||
throw (BackingStoreException) e.getException();
|
||||
}
|
||||
}
|
||||
private void syncSpiPrivileged() throws BackingStoreException {
|
||||
if (isRemoved())
|
||||
throw new IllegalStateException("Node has been removed");
|
||||
if (prefsCache == null)
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2000, 2022, 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
|
||||
@ -27,8 +27,6 @@ package java.util.prefs;
|
||||
|
||||
import java.util.StringTokenizer;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
|
||||
import sun.util.logging.PlatformLogger;
|
||||
|
||||
@ -50,13 +48,9 @@ class WindowsPreferences extends AbstractPreferences {
|
||||
loadPrefsLib();
|
||||
}
|
||||
|
||||
@SuppressWarnings({"removal", "restricted"})
|
||||
@SuppressWarnings("restricted")
|
||||
private static void loadPrefsLib() {
|
||||
PrivilegedAction<Void> load = () -> {
|
||||
System.loadLibrary("prefs");
|
||||
return null;
|
||||
};
|
||||
AccessController.doPrivileged(load);
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user