8344337: SecurityManager cleanup in java.prefs module

Reviewed-by: lancea, bpb, rriggs, iris
This commit is contained in:
Brent Christian 2024-11-26 01:17:37 +00:00
parent 1c7f34d3dd
commit 4d4cef800a
6 changed files with 181 additions and 344 deletions

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * 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; import java.util.Objects;
class MacOSXPreferences extends AbstractPreferences { class MacOSXPreferences extends AbstractPreferences {
// fixme need security checks?
// CF preferences file name for Java nodes with short names // CF preferences file name for Java nodes with short names
// This value is also in MacOSXPreferencesFile.c // This value is also in MacOSXPreferencesFile.c
private static final String defaultAppName = "com.apple.java.util.prefs"; private static final String defaultAppName = "com.apple.java.util.prefs";

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
@ -82,15 +82,9 @@ class MacOSXPreferencesFile {
loadPrefsLib(); loadPrefsLib();
} }
@SuppressWarnings({"removal", "restricted"}) @SuppressWarnings("restricted")
private static void loadPrefsLib() { private static void loadPrefsLib() {
java.security.AccessController.doPrivileged( System.loadLibrary("prefs");
new java.security.PrivilegedAction<Void>() {
public Void run() {
System.loadLibrary("prefs");
return null;
}
});
} }
private static class FlushTask extends TimerTask { private static class FlushTask extends TimerTask {

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * 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.util.*;
import java.io.*; import java.io.*;
import java.security.AccessController;
import java.security.PrivilegedAction;
/** /**
* This class provides a skeletal implementation of the {@link Preferences} * This class provides a skeletal implementation of the {@link Preferences}
@ -1058,14 +1056,8 @@ public abstract class AbstractPreferences extends Preferences {
* preference tree, {@code false} if it's in the system * preference tree, {@code false} if it's in the system
* preference tree. * preference tree.
*/ */
@SuppressWarnings("removal")
public boolean isUserNode() { public boolean isUserNode() {
return AccessController.doPrivileged( return root == Preferences.userRoot();
new PrivilegedAction<Boolean>() {
public Boolean run() {
return root == Preferences.userRoot();
}
}).booleanValue();
} }
public void addPreferenceChangeListener(PreferenceChangeListener pcl) { public void addPreferenceChangeListener(PreferenceChangeListener pcl) {

View File

@ -30,20 +30,10 @@ import jdk.internal.util.OperatingSystem;
import java.io.InputStream; import java.io.InputStream;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.security.AccessController;
import java.security.Permission;
import java.security.PrivilegedAction;
import java.util.Iterator; import java.util.Iterator;
import java.util.ServiceLoader; import java.util.ServiceLoader;
import java.util.ServiceConfigurationError; 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 * A node in a hierarchical collection of preference data. This class
* allows applications to store and retrieve user and system * allows applications to store and retrieve user and system
@ -227,19 +217,10 @@ public abstract class Preferences {
private static final PreferencesFactory factory = factory(); private static final PreferencesFactory factory = factory();
@SuppressWarnings("removal")
private static PreferencesFactory factory() { private static PreferencesFactory factory() {
// 1. Try user-specified system property // 1. Try user-specified system property
String factoryName = AccessController.doPrivileged( String factoryName = System.getProperty("java.util.prefs.PreferencesFactory");
new PrivilegedAction<String>() {
public String run() {
return System.getProperty(
"java.util.prefs.PreferencesFactory");}});
if (factoryName != null) { 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 { try {
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
Object result =Class.forName(factoryName, false, Object result =Class.forName(factoryName, false,
@ -250,10 +231,6 @@ public abstract class Preferences {
try { try {
// workaround for javaws, plugin, // workaround for javaws, plugin,
// load factory class using non-system classloader // load factory class using non-system classloader
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(new java.security.AllPermission());
}
@SuppressWarnings("deprecation") @SuppressWarnings("deprecation")
Object result = Class.forName(factoryName, false, Object result = Class.forName(factoryName, false,
Thread.currentThread() 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 // 2. Try service provider interface
Iterator<PreferencesFactory> itr = ServiceLoader Iterator<PreferencesFactory> itr = ServiceLoader
.load(PreferencesFactory.class, ClassLoader.getSystemClassLoader()) .load(PreferencesFactory.class, ClassLoader.getSystemClassLoader())
@ -427,24 +396,12 @@ public abstract class Preferences {
return "/" + packageName.replace('.', '/'); 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. * Returns the root preference node for the calling user.
* *
* @return the root preference node for the calling user. * @return the root preference node for the calling user.
*/ */
public static Preferences userRoot() { public static Preferences userRoot() {
@SuppressWarnings("removal")
SecurityManager security = System.getSecurityManager();
if (security != null)
security.checkPermission(prefsPerm);
return factory.userRoot(); return factory.userRoot();
} }
@ -454,11 +411,6 @@ public abstract class Preferences {
* @return the root preference node for the system. * @return the root preference node for the system.
*/ */
public static Preferences systemRoot() { public static Preferences systemRoot() {
@SuppressWarnings("removal")
SecurityManager security = System.getSecurityManager();
if (security != null)
security.checkPermission(prefsPerm);
return factory.systemRoot(); return factory.systemRoot();
} }

View File

@ -27,9 +27,6 @@ package java.util.prefs;
import java.util.*; import java.util.*;
import java.io.*; import java.io.*;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.PrivilegedExceptionAction;
import java.security.PrivilegedActionException; import java.security.PrivilegedActionException;
import sun.util.logging.PlatformLogger; import sun.util.logging.PlatformLogger;
@ -53,13 +50,9 @@ class FileSystemPreferences extends AbstractPreferences {
loadPrefsLib(); loadPrefsLib();
} }
@SuppressWarnings({"removal", "restricted"}) @SuppressWarnings("restricted")
private static void loadPrefsLib() { private static void loadPrefsLib() {
PrivilegedAction<Void> load = () -> { System.loadLibrary("prefs");
System.loadLibrary("prefs");
return null;
};
AccessController.doPrivileged(load);
} }
/** /**
@ -67,8 +60,7 @@ class FileSystemPreferences extends AbstractPreferences {
*/ */
@SuppressWarnings("removal") @SuppressWarnings("removal")
private static final int SYNC_INTERVAL = Math.max(1, 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 * Returns logger for error messages. Backing store exceptions are logged at
@ -117,52 +109,47 @@ class FileSystemPreferences extends AbstractPreferences {
return root; return root;
} }
@SuppressWarnings("removal")
private static void setupUserRoot() { private static void setupUserRoot() {
AccessController.doPrivileged(new PrivilegedAction<Void>() { userRootDir =
public Void run() { new File(System.getProperty("java.util.prefs.userRoot",
userRootDir =
new File(System.getProperty("java.util.prefs.userRoot",
System.getProperty("user.home")), ".java/.userPrefs"); System.getProperty("user.home")), ".java/.userPrefs");
// Attempt to create root dir if it does not yet exist. // Attempt to create root dir if it does not yet exist.
if (!userRootDir.exists()) { if (!userRootDir.exists()) {
if (userRootDir.mkdirs()) { if (userRootDir.mkdirs()) {
try {
chmod(userRootDir.getCanonicalPath(), USER_RWX);
} catch (IOException e) {
getLogger().warning("Could not change permissions" +
" on userRoot directory. ");
}
getLogger().info("Created user preferences directory.");
}
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())
try { try {
// create if does not exist. chmod(userRootDir.getCanonicalPath(), USER_RWX);
userRootModFile.createNewFile();
// Only user can read/write userRootModFile.
int result = chmod(userRootModFile.getCanonicalPath(),
USER_READ_WRITE);
if (result !=0)
getLogger().warning("Problem creating userRoot " +
"mod file. Chmod failed on " +
userRootModFile.getCanonicalPath() +
" Unix error code " + result);
} catch (IOException e) { } catch (IOException e) {
getLogger().warning(e.toString()); getLogger().warning("Could not change permissions" +
" on userRoot directory. ");
} }
userRootModTime = userRootModFile.lastModified(); getLogger().info("Created user preferences directory.");
return null; } 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()) {
try {
// create if does not exist.
userRootModFile.createNewFile();
// Only user can read/write userRootModFile.
int result = chmod(userRootModFile.getCanonicalPath(),
USER_READ_WRITE);
if (result != 0)
getLogger().warning("Problem creating userRoot " +
"mod file. Chmod failed on " +
userRootModFile.getCanonicalPath() +
" Unix error code " + result);
} catch (IOException e) {
getLogger().warning(e.toString());
}
}
userRootModTime = userRootModFile.lastModified();
} }
@ -185,58 +172,54 @@ class FileSystemPreferences extends AbstractPreferences {
return root; return root;
} }
@SuppressWarnings("removal")
private static void setupSystemRoot() { private static void setupSystemRoot() {
AccessController.doPrivileged(new PrivilegedAction<Void>() { String systemPrefsDirName =
public Void run() { System.getProperty("java.util.prefs.systemRoot", "/etc/.java");
String systemPrefsDirName = systemRootDir =
System.getProperty("java.util.prefs.systemRoot","/etc/.java"); new File(systemPrefsDirName, ".systemPrefs");
systemRootDir = // Attempt to create root dir if it does not yet exist.
new File(systemPrefsDirName, ".systemPrefs"); if (!systemRootDir.exists()) {
// Attempt to create root dir if it does not yet exist. // system root does not exist in /etc/.java
if (!systemRootDir.exists()) { // Switching to java.home
// system root does not exist in /etc/.java systemRootDir =
// Switching to java.home new File(System.getProperty("java.home"),
systemRootDir = ".systemPrefs");
new File(System.getProperty("java.home"), if (!systemRootDir.exists()) {
".systemPrefs"); if (systemRootDir.mkdirs()) {
if (!systemRootDir.exists()) { getLogger().info(
if (systemRootDir.mkdirs()) { "Created system preferences directory "
getLogger().info( + "in java.home.");
"Created system preferences directory " try {
+ "in java.home."); chmod(systemRootDir.getCanonicalPath(),
try { USER_RWX_ALL_RX);
chmod(systemRootDir.getCanonicalPath(), } catch (IOException e) {
USER_RWX_ALL_RX);
} catch (IOException e) {
}
} else {
getLogger().warning("Could not create "
+ "system preferences directory. System "
+ "preferences are unusable.");
}
} }
} else {
getLogger().warning("Could not create "
+ "system preferences directory. System "
+ "preferences are unusable.");
} }
isSystemRootWritable = systemRootDir.canWrite();
systemLockFile = new File(systemRootDir, ".system.lock");
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)
getLogger().warning("Chmod failed on " +
systemRootModFile.getCanonicalPath() +
" Unix error code " + result);
} catch (IOException e) { getLogger().warning(e.toString());
}
systemRootModTime = systemRootModFile.lastModified();
return null;
} }
}); }
isSystemRootWritable = systemRootDir.canWrite();
systemLockFile = new File(systemRootDir, ".system.lock");
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) {
getLogger().warning("Chmod failed on " +
systemRootModFile.getCanonicalPath() +
" Unix error code " + result);
}
} catch (IOException e) {
getLogger().warning(e.toString());
}
}
systemRootModTime = systemRootModFile.lastModified();
} }
@ -456,7 +439,6 @@ class FileSystemPreferences extends AbstractPreferences {
addShutdownHook(); addShutdownHook();
} }
@SuppressWarnings("removal")
private static void addShutdownHook() { private static void addShutdownHook() {
// Add periodic timer task to periodically sync cached prefs // Add periodic timer task to periodically sync cached prefs
syncTimer.schedule(new TimerTask() { syncTimer.schedule(new TimerTask() {
@ -466,16 +448,11 @@ class FileSystemPreferences extends AbstractPreferences {
}, SYNC_INTERVAL*1000, SYNC_INTERVAL*1000); }, SYNC_INTERVAL*1000, SYNC_INTERVAL*1000);
// Add shutdown hook to flush cached prefs on normal termination // Add shutdown hook to flush cached prefs on normal termination
AccessController.doPrivileged(new PrivilegedAction<Void>() { Runtime.getRuntime().addShutdownHook(
public Void run() { new Thread(null, null, "Sync Timer Thread", 0, false) {
Runtime.getRuntime().addShutdownHook( public void run() {
new Thread(null, null, "Sync Timer Thread", 0, false) { syncTimer.cancel();
public void run() { syncWorld();
syncTimer.cancel();
syncWorld();
}
});
return null;
} }
}); });
} }
@ -526,19 +503,13 @@ class FileSystemPreferences extends AbstractPreferences {
* parent node and name. This constructor, called from childSpi, * parent node and name. This constructor, called from childSpi,
* is used to make every node except for the two //roots. * is used to make every node except for the two //roots.
*/ */
@SuppressWarnings("removal")
private FileSystemPreferences(FileSystemPreferences parent, String name) { private FileSystemPreferences(FileSystemPreferences parent, String name) {
super(parent, name); super(parent, name);
isUserNode = parent.isUserNode; isUserNode = parent.isUserNode;
dir = new File(parent.dir, dirName(name)); dir = new File(parent.dir, dirName(name));
prefsFile = new File(dir, "prefs.xml"); prefsFile = new File(dir, "prefs.xml");
tmpFile = new File(dir, "prefs.tmp"); tmpFile = new File(dir, "prefs.tmp");
AccessController.doPrivileged(new PrivilegedAction<Void>() { newNode = !dir.exists();
public Void run() {
newNode = !dir.exists();
return null;
}
});
if (newNode) { if (newNode) {
// These 2 things guarantee node will get written at next flush/sync // These 2 things guarantee node will get written at next flush/sync
prefsCache = new TreeMap<>(); prefsCache = new TreeMap<>();
@ -596,43 +567,32 @@ class FileSystemPreferences extends AbstractPreferences {
* fails, a BackingStoreException is thrown and both prefsCache and * fails, a BackingStoreException is thrown and both prefsCache and
* lastSyncTime are unaffected by the call. * lastSyncTime are unaffected by the call.
*/ */
@SuppressWarnings("removal")
private void loadCache() throws BackingStoreException { private void loadCache() throws BackingStoreException {
Map<String, String> m = new TreeMap<>();
long newLastSyncTime = 0;
try { try {
AccessController.doPrivileged( newLastSyncTime = prefsFile.lastModified();
new PrivilegedExceptionAction<Void>() { try (FileInputStream fis = new FileInputStream(prefsFile)) {
public Void run() throws BackingStoreException { XmlSupport.importMap(fis, m);
Map<String, String> m = new TreeMap<>(); }
long newLastSyncTime = 0; } catch(Exception e) {
try { if (e instanceof InvalidPreferencesFormatException) {
newLastSyncTime = prefsFile.lastModified(); getLogger().warning("Invalid preferences format in "
try (FileInputStream fis = new FileInputStream(prefsFile)) { + prefsFile.getPath());
XmlSupport.importMap(fis, m); prefsFile.renameTo( new File(
} prefsFile.getParentFile(),
} catch(Exception e) { "IncorrectFormatPrefs.xml"));
if (e instanceof InvalidPreferencesFormatException) { m = new TreeMap<>();
getLogger().warning("Invalid preferences format in " } else if (e instanceof FileNotFoundException) {
+ prefsFile.getPath()); getLogger().warning("Prefs file removed in background "
prefsFile.renameTo( new File( + prefsFile.getPath());
prefsFile.getParentFile(), } else {
"IncorrectFormatPrefs.xml")); throw new BackingStoreException(e);
m = new TreeMap<>(); }
} else if (e instanceof FileNotFoundException) {
getLogger().warning("Prefs file removed in background "
+ prefsFile.getPath());
} else {
throw new BackingStoreException(e);
}
}
// Attempt succeeded; update state
prefsCache = m;
lastSyncTime = newLastSyncTime;
return null;
}
});
} catch (PrivilegedActionException e) {
throw (BackingStoreException) e.getException();
} }
// Attempt succeeded; update state
prefsCache = m;
lastSyncTime = newLastSyncTime;
} }
/** /**
@ -644,32 +604,21 @@ class FileSystemPreferences extends AbstractPreferences {
* and lastSyncTime will be unaffected by this call. This call will * and lastSyncTime will be unaffected by this call. This call will
* NEVER leave prefsFile in a corrupt state. * NEVER leave prefsFile in a corrupt state.
*/ */
@SuppressWarnings("removal")
private void writeBackCache() throws BackingStoreException { private void writeBackCache() throws BackingStoreException {
try { try {
AccessController.doPrivileged( if (!dir.exists() && !dir.mkdirs())
new PrivilegedExceptionAction<Void>() { throw new BackingStoreException(dir +
public Void run() throws BackingStoreException { " create failed.");
try { try (FileOutputStream fos = new FileOutputStream(tmpFile)) {
if (!dir.exists() && !dir.mkdirs()) XmlSupport.exportMap(fos, prefsCache);
throw new BackingStoreException(dir + }
" create failed."); if (!tmpFile.renameTo(prefsFile))
try (FileOutputStream fos = new FileOutputStream(tmpFile)) { throw new BackingStoreException("Can't rename " +
XmlSupport.exportMap(fos, prefsCache); tmpFile + " to " + prefsFile);
} } catch(BackingStoreException e) {
if (!tmpFile.renameTo(prefsFile)) throw e;
throw new BackingStoreException("Can't rename " + } catch(Exception e) {
tmpFile + " to " + prefsFile); throw new BackingStoreException(e);
} catch(Exception e) {
if (e instanceof BackingStoreException)
throw (BackingStoreException)e;
throw new BackingStoreException(e);
}
return null;
}
});
} catch (PrivilegedActionException e) {
throw (BackingStoreException) e.getException();
} }
} }
@ -678,21 +627,15 @@ class FileSystemPreferences extends AbstractPreferences {
return prefsCache.keySet().toArray(new String[prefsCache.size()]); return prefsCache.keySet().toArray(new String[prefsCache.size()]);
} }
@SuppressWarnings("removal")
protected String[] childrenNamesSpi() { protected String[] childrenNamesSpi() {
return AccessController.doPrivileged( List<String> result = new ArrayList<>();
new PrivilegedAction<String[]>() { File[] dirContents = dir.listFiles();
public String[] run() { if (dirContents != null) {
List<String> result = new ArrayList<>(); for (int i = 0; i < dirContents.length; i++)
File[] dirContents = dir.listFiles(); if (dirContents[i].isDirectory())
if (dirContents != null) { result.add(nodeName(dirContents[i].getName()));
for (int i = 0; i < dirContents.length; i++) }
if (dirContents[i].isDirectory()) return result.toArray(EMPTY_STRING_ARRAY);
result.add(nodeName(dirContents[i].getName()));
}
return result.toArray(EMPTY_STRING_ARRAY);
}
});
} }
private static final String[] EMPTY_STRING_ARRAY = new String[0]; private static final String[] EMPTY_STRING_ARRAY = new String[0];
@ -717,42 +660,30 @@ class FileSystemPreferences extends AbstractPreferences {
/** /**
* Called with file lock held (in addition to node locks). * Called with file lock held (in addition to node locks).
*/ */
@SuppressWarnings("removal")
protected void removeNodeSpi() throws BackingStoreException { protected void removeNodeSpi() throws BackingStoreException {
try { if (changeLog.contains(nodeCreate)) {
AccessController.doPrivileged( changeLog.remove(nodeCreate);
new PrivilegedExceptionAction<Void>() { nodeCreate = null;
public Void run() throws BackingStoreException { return;
if (changeLog.contains(nodeCreate)) {
changeLog.remove(nodeCreate);
nodeCreate = null;
return null;
}
if (!dir.exists())
return null;
prefsFile.delete();
tmpFile.delete();
// dir should be empty now. If it's not, empty it
File[] junk = dir.listFiles();
if (junk.length != 0) {
getLogger().warning(
"Found extraneous files when removing node: "
+ Arrays.asList(junk));
for (int i=0; i<junk.length; i++)
junk[i].delete();
}
if (!dir.delete())
throw new BackingStoreException("Couldn't delete dir: "
+ dir);
return null;
}
});
} catch (PrivilegedActionException e) {
throw (BackingStoreException) e.getException();
} }
if (!dir.exists())
return;
prefsFile.delete();
tmpFile.delete();
// dir should be empty now. If it's not, empty it
File[] junk = dir.listFiles();
if (junk.length != 0) {
getLogger().warning(
"Found extraneous files when removing node: "
+ Arrays.asList(junk));
for (int i=0; i<junk.length; i++)
junk[i].delete();
}
if (!dir.delete())
throw new BackingStoreException("Couldn't delete dir: "
+ dir);
} }
@SuppressWarnings("removal")
public synchronized void sync() throws BackingStoreException { public synchronized void sync() throws BackingStoreException {
boolean userNode = isUserNode(); boolean userNode = isUserNode();
boolean shared; boolean shared;
@ -765,58 +696,34 @@ class FileSystemPreferences extends AbstractPreferences {
shared = !isSystemRootWritable; shared = !isSystemRootWritable;
} }
synchronized (isUserNode()? userLockFile:systemLockFile) { synchronized (isUserNode()? userLockFile:systemLockFile) {
if (!lockFile(shared)) if (!lockFile(shared)) {
throw(new BackingStoreException("Couldn't get file lock.")); throw (new BackingStoreException("Couldn't get file lock."));
final Long newModTime = }
AccessController.doPrivileged( long nmt;
new PrivilegedAction<Long>() { if (isUserNode()) {
public Long run() { nmt = userRootModFile.lastModified();
long nmt; isUserRootModified = userRootModTime == nmt;
if (isUserNode()) { } else {
nmt = userRootModFile.lastModified(); nmt = systemRootModFile.lastModified();
isUserRootModified = userRootModTime == nmt; isSystemRootModified = systemRootModTime == nmt;
} else { }
nmt = systemRootModFile.lastModified(); final long newModTime = nmt;
isSystemRootModified = systemRootModTime == nmt;
}
return nmt;
}
});
try { try {
super.sync(); super.sync();
AccessController.doPrivileged(new PrivilegedAction<Void>() { if (isUserNode()) {
public Void run() { userRootModTime = newModTime + 1000;
if (isUserNode()) { userRootModFile.setLastModified(userRootModTime);
userRootModTime = newModTime.longValue() + 1000; } else {
userRootModFile.setLastModified(userRootModTime); systemRootModTime = newModTime + 1000;
} else { systemRootModFile.setLastModified(systemRootModTime);
systemRootModTime = newModTime.longValue() + 1000; }
systemRootModFile.setLastModified(systemRootModTime);
}
return null;
}
});
} finally { } finally {
unlockFile(); unlockFile();
} }
} }
} }
@SuppressWarnings("removal")
protected void syncSpi() throws BackingStoreException { 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()) if (isRemoved())
throw new IllegalStateException("Node has been removed"); throw new IllegalStateException("Node has been removed");
if (prefsCache == null) if (prefsCache == null)

View File

@ -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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * 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.util.StringTokenizer;
import java.io.ByteArrayOutputStream; import java.io.ByteArrayOutputStream;
import java.security.AccessController;
import java.security.PrivilegedAction;
import sun.util.logging.PlatformLogger; import sun.util.logging.PlatformLogger;
@ -50,13 +48,9 @@ class WindowsPreferences extends AbstractPreferences {
loadPrefsLib(); loadPrefsLib();
} }
@SuppressWarnings({"removal", "restricted"}) @SuppressWarnings("restricted")
private static void loadPrefsLib() { private static void loadPrefsLib() {
PrivilegedAction<Void> load = () -> { System.loadLibrary("prefs");
System.loadLibrary("prefs");
return null;
};
AccessController.doPrivileged(load);
} }
/** /**