8066709: Make some JDK system properties read only

Reviewed-by: lancea, sundar, bchristi, weijun, mchung, alanb, mullan
This commit is contained in:
Roger Riggs 2018-06-27 09:36:34 -04:00
parent cad47f4a03
commit 4098f2560a
25 changed files with 215 additions and 46 deletions

View File

@ -29,8 +29,8 @@ import java.nio.file.*;
import java.nio.file.attribute.*;
import java.nio.file.spi.FileTypeDetector;
import java.io.IOException;
import java.security.AccessController;
import sun.security.action.GetPropertyAction;
import jdk.internal.util.StaticProperty;
/**
* Linux implementation of FileSystemProvider
@ -102,7 +102,7 @@ public class LinuxFileSystemProvider extends UnixFileSystemProvider {
@Override
FileTypeDetector getFileTypeDetector() {
String userHome = GetPropertyAction.privilegedGetProperty("user.home");
String userHome = StaticProperty.userHome();
Path userMimeTypes = Path.of(userHome, ".mime.types");
Path etcMimeTypes = Path.of("/etc/mime.types");

View File

@ -27,6 +27,7 @@ package sun.nio.fs;
import java.nio.file.Path;
import java.nio.file.spi.FileTypeDetector;
import jdk.internal.util.StaticProperty;
import sun.security.action.GetPropertyAction;
/**
@ -45,8 +46,7 @@ public class MacOSXFileSystemProvider extends BsdFileSystemProvider {
@Override
FileTypeDetector getFileTypeDetector() {
Path userMimeTypes = Path.of(GetPropertyAction
.privilegedGetProperty("user.home"), ".mime.types");
Path userMimeTypes = Path.of(StaticProperty.userHome(), ".mime.types");
return chain(new MimeTypesFileTypeDetector(userMimeTypes),
new UTIFileTypeDetector());

View File

@ -59,6 +59,7 @@ import java.util.function.Supplier;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Stream;
import jdk.internal.util.StaticProperty;
import jdk.internal.module.ModuleBootstrap;
import jdk.internal.module.ServicesCatalog;
import jdk.internal.reflect.CallerSensitive;
@ -669,7 +670,16 @@ public final class System {
* {@code getProperties} operation, it may choose to permit the
* {@link #getProperty(String)} operation.
*
* @implNote In addition to the standard system properties, the system
* @apiNote
* <strong>Changing a standard system property may have unpredictable results
* unless otherwise specified.</strong>
* Property values may be cached during initialization or on first use.
* Setting a standard property after initialization using {@link #getProperties()},
* {@link #setProperties(Properties)}, {@link #setProperty(String, String)}, or
* {@link #clearProperty(String)} may not have the desired effect.
*
* @implNote
* In addition to the standard system properties, the system
* properties may include the following keys:
* <table class="striped">
* <caption style="display:none">Shows property keys and associated values</caption>
@ -736,6 +746,11 @@ public final class System {
* {@code null}, then the current set of system properties is
* forgotten.
*
* @apiNote
* <strong>Changing a standard system property may have unpredictable results
* unless otherwise specified</strong>.
* See {@linkplain #getProperties getProperties} for details.
*
* @param props the new system properties.
* @throws SecurityException if a security manager exists and its
* {@code checkPropertiesAccess} method doesn't allow access
@ -768,6 +783,11 @@ public final class System {
* properties is first created and initialized in the same manner as
* for the {@code getProperties} method.
*
* @apiNote
* <strong>Changing a standard system property may have unpredictable results
* unless otherwise specified</strong>.
* See {@linkplain #getProperties getProperties} for details.
*
* @param key the name of the system property.
* @return the string value of the system property,
* or {@code null} if there is no property with that key.
@ -837,6 +857,11 @@ public final class System {
* If no exception is thrown, the specified property is set to the given
* value.
*
* @apiNote
* <strong>Changing a standard system property may have unpredictable results
* unless otherwise specified</strong>.
* See {@linkplain #getProperties getProperties} for details.
*
* @param key the name of the system property.
* @param value the value of the system property.
* @return the previous value of the system property,
@ -875,6 +900,11 @@ public final class System {
* permission. This may result in a SecurityException being thrown.
* If no exception is thrown, the specified property is removed.
*
* @apiNote
* <strong>Changing a standard system property may have unpredictable results
* unless otherwise specified</strong>.
* See {@linkplain #getProperties getProperties} method for details.
*
* @param key the name of the system property to be removed.
* @return the previous string value of the system property,
* or {@code null} if there was no property with that key.
@ -1927,6 +1957,7 @@ public final class System {
VM.saveAndRemoveProperties(props);
lineSeparator = props.getProperty("line.separator");
StaticProperty.javaHome(); // Load StaticProperty to cache the property values
VersionProps.init();
FileInputStream fdIn = new FileInputStream(FileDescriptor.in);

View File

@ -30,10 +30,11 @@ import java.io.BufferedOutputStream;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.PrivilegedExceptionAction;
import jdk.internal.util.StaticProperty;
import sun.net.SocksProxy;
import sun.net.spi.DefaultProxySelector;
import sun.net.www.ParseUtil;
import sun.security.action.GetPropertyAction;
/* import org.ietf.jgss.*; */
/**
@ -178,7 +179,7 @@ class SocksSocketImpl extends PlainSocketImpl implements SocksConsts {
userName = pw.getUserName();
password = new String(pw.getPassword());
} else {
userName = GetPropertyAction.privilegedGetProperty("user.name");
userName = StaticProperty.userName();
}
if (userName == null)
return false;
@ -1088,7 +1089,7 @@ class SocksSocketImpl extends PlainSocketImpl implements SocksConsts {
userName = System.getProperty("user.name");
} catch (SecurityException se) { /* swallow Exception */ }
} else {
userName = GetPropertyAction.privilegedGetProperty("user.name");
userName = StaticProperty.userName();
}
return userName;
}

View File

@ -31,6 +31,7 @@ import java.io.*;
import java.net.URL;
import jdk.internal.misc.SharedSecrets;
import jdk.internal.util.StaticProperty;
import sun.security.util.Debug;
import sun.security.util.PropertyExpander;
@ -214,7 +215,7 @@ public final class Security {
// maybe check for a system property which will specify where to
// look. Someday.
String sep = File.separator;
return new File(System.getProperty("java.home") + sep + "conf" + sep +
return new File(StaticProperty.javaHome() + sep + "conf" + sep +
"security" + sep + filename);
}

View File

@ -61,19 +61,19 @@
*/
package java.time.zone;
import jdk.internal.util.StaticProperty;
import java.io.ByteArrayInputStream;
import java.io.BufferedInputStream;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.StreamCorruptedException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.NavigableMap;
import java.util.Objects;
import java.util.Set;
import java.util.TreeMap;
import java.util.concurrent.ConcurrentHashMap;
@ -106,7 +106,7 @@ final class TzdbZoneRulesProvider extends ZoneRulesProvider {
*/
public TzdbZoneRulesProvider() {
try {
String libDir = System.getProperty("java.home") + File.separator + "lib";
String libDir = StaticProperty.javaHome() + File.separator + "lib";
try (DataInputStream dis = new DataInputStream(
new BufferedInputStream(new FileInputStream(
new File(libDir, "tzdb.dat"))))) {

View File

@ -42,6 +42,8 @@ import java.util.regex.Pattern;
import java.util.regex.Matcher;
import java.util.spi.CurrencyNameProvider;
import java.util.stream.Collectors;
import jdk.internal.util.StaticProperty;
import sun.util.locale.provider.CalendarDataUtility;
import sun.util.locale.provider.LocaleServiceProviderPool;
import sun.util.logging.PlatformLogger;
@ -236,7 +238,7 @@ public final class Currency implements Serializable {
// look for the properties file for overrides
String propsFile = System.getProperty("java.util.currency.data");
if (propsFile == null) {
propsFile = System.getProperty("java.home") + File.separator + "lib" +
propsFile = StaticProperty.javaHome() + File.separator + "lib" +
File.separator + "currency.properties";
}
try {
@ -578,7 +580,7 @@ public final class Currency implements Serializable {
/**
* Returns the 3 digit ISO 4217 numeric code of this currency as a {@code String}.
* Unlike {@link getNumericCode()}, which returns the numeric code as {@code int},
* Unlike {@link #getNumericCode()}, which returns the numeric code as {@code int},
* this method always returns the numeric code as a 3 digit string.
* e.g. a numeric value of 32 would be returned as "032",
* and a numeric value of 6 would be returned as "006".

View File

@ -39,10 +39,9 @@
package java.util;
import java.io.Serializable;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.time.ZoneId;
import java.util.Properties;
import jdk.internal.util.StaticProperty;
import sun.security.action.GetPropertyAction;
import sun.util.calendar.ZoneInfo;
import sun.util.calendar.ZoneInfoFile;
@ -667,7 +666,7 @@ public abstract class TimeZone implements Serializable, Cloneable {
// if the time zone ID is not set (yet), perform the
// platform to Java time zone ID mapping.
if (zoneID == null || zoneID.isEmpty()) {
String javaHome = props.getProperty("java.home");
String javaHome = StaticProperty.javaHome();
try {
zoneID = getSystemTimeZoneID(javaHome);
if (zoneID == null) {

View File

@ -57,6 +57,8 @@ import java.security.*;
import java.security.Provider.Service;
import jdk.internal.util.StaticProperty;
import sun.security.jca.*;
import sun.security.jca.GetInstance.Instance;
import sun.security.util.Debug;
@ -71,8 +73,8 @@ import sun.security.util.Debug;
*/
final class JceSecurity {
private static final Debug debug = Debug.getInstance("jca");
static final SecureRandom RANDOM = new SecureRandom();
@ -307,7 +309,7 @@ final class JceSecurity {
// Prepend java.home to get the full path. normalize() in
// case an extra "." or ".." snuck in somehow.
String javaHomeProperty = System.getProperty("java.home");
String javaHomeProperty = StaticProperty.javaHome();
Path javaHomePolicyPath = Paths.get(javaHomeProperty, "conf",
"security", "policy").normalize();
Path cryptoPolicyPath = Paths.get(javaHomeProperty, "conf", "security",

View File

@ -46,6 +46,7 @@ import jdk.internal.misc.JavaLangAccess;
import jdk.internal.misc.SharedSecrets;
import jdk.internal.module.Modules;
import jdk.internal.module.ServicesCatalog;
import jdk.internal.util.StaticProperty;
/**
* Find resources and packages in modules defined to the boot class loader or
@ -57,7 +58,7 @@ public class BootLoader {
// The unnamed module for the boot loader
private static final Module UNNAMED_MODULE;
private static final String JAVA_HOME = System.getProperty("java.home");
private static final String JAVA_HOME = StaticProperty.javaHome();
static {
UNNAMED_MODULE = SharedSecrets.getJavaLangAccess().defineUnnamedModule(null);

View File

@ -61,6 +61,7 @@ import jdk.internal.jimage.ImageReader;
import jdk.internal.jimage.ImageReaderFactory;
import jdk.internal.misc.JavaNetUriAccess;
import jdk.internal.misc.SharedSecrets;
import jdk.internal.util.StaticProperty;
import jdk.internal.module.ModuleHashes.HashSupplier;
/**
@ -183,7 +184,7 @@ public final class SystemModuleFinders {
}
// probe to see if this is an images build
String home = System.getProperty("java.home");
String home = StaticProperty.javaHome();
Path modules = Path.of(home, "lib", "modules");
if (Files.isRegularFile(modules)) {
if (USE_FAST_PATH) {

View File

@ -0,0 +1,107 @@
/*
* Copyright (c) 2018, 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
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package jdk.internal.util;
/**
* System Property access for internal use only.
* Read-only access to System property values initialized during Phase 1
* are cached. Setting, clearing, or modifying the value using
* {@link System#setProperty) or {@link System#getProperties()} is ignored.
* <strong>{@link SecurityManager#checkPropertyAccess} is NOT checked
* in these access methods. The caller of these methods should take care to ensure
* that the returned property is not made accessible to untrusted code.</strong>
*/
public final class StaticProperty {
// The class static initialization is triggered to initialize these final
// fields during init Phase 1 and before a security manager is set.
private static final String JAVA_HOME = initProperty("java.home");
private static final String USER_HOME = initProperty("user.home");
private static final String USER_DIR = initProperty("user.dir");
private static final String USER_NAME = initProperty("user.name");
private StaticProperty() {}
private static String initProperty(String key) {
String v = System.getProperty(key);
if (v == null) {
throw new InternalError("null property: " + key);
}
return v;
}
/**
* Return the {@code java.home} system property.
*
* <strong>{@link SecurityManager#checkPropertyAccess} is NOT checked
* in this method. The caller of this method should take care to ensure
* that the returned property is not made accessible to untrusted code.</strong>
*
* @return the {@code java.home} system property
*/
public static String javaHome() {
return JAVA_HOME;
}
/**
* Return the {@code user.home} system property.
*
* <strong>{@link SecurityManager#checkPropertyAccess} is NOT checked
* in this method. The caller of this method should take care to ensure
* that the returned property is not made accessible to untrusted code.</strong>
*
* @return the {@code user.home} system property
*/
public static String userHome() {
return USER_HOME;
}
/**
* Return the {@code user.dir} system property.
*
* <strong>{@link SecurityManager#checkPropertyAccess} is NOT checked
* in this method. The caller of this method should take care to ensure
* that the returned property is not made accessible to untrusted code.</strong>
*
* @return the {@code user.dir} system property
*/
public static String userDir() {
return USER_DIR;
}
/**
* Return the {@code user.name} system property.
*
* <strong>{@link SecurityManager#checkPropertyAccess} is NOT checked
* in this method. The caller of this method should take care to ensure
* that the returned property is not made accessible to untrusted code.</strong>
*
* @return the {@code user.name} system property
*/
public static String userName() {
return USER_NAME;
}
}

View File

@ -24,6 +24,8 @@
*/
package sun.net;
import jdk.internal.util.StaticProperty;
import java.io.*;
import java.security.AccessController;
import java.security.PrivilegedAction;
@ -57,7 +59,7 @@ public class NetProperties {
* the file is in jre/lib/net.properties
*/
private static void loadDefaultProperties() {
String fname = System.getProperty("java.home");
String fname = StaticProperty.javaHome();
if (fname == null) {
throw new Error("Can't find java.home ??");
}

View File

@ -24,6 +24,8 @@
*/
package sun.net.www;
import jdk.internal.util.StaticProperty;
import java.io.*;
import java.net.FileNameMap;
import java.util.Hashtable;
@ -53,7 +55,7 @@ public class MimeTable implements FileNameMap {
mailcapLocations = new String[] {
System.getProperty("user.mailcap"),
System.getProperty("user.home") + "/.mailcap",
StaticProperty.userHome() + "/.mailcap",
"/etc/mailcap",
"/usr/etc/mailcap",
"/usr/local/etc/mailcap",
@ -384,7 +386,12 @@ public class MimeTable implements FileNameMap {
Properties properties = getAsProperties();
properties.put("temp.file.template", tempFileTemplate);
String tag;
String user = System.getProperty("user.name");
// Perform the property security check for user.name
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPropertyAccess("user.name");
}
String user = StaticProperty.userName();
if (user != null) {
tag = "; customized for " + user;
properties.store(os, filePreamble + tag);

View File

@ -30,6 +30,8 @@ import java.net.InetAddress;
import java.net.SocketPermission;
import java.io.*;
import java.security.Permission;
import jdk.internal.util.StaticProperty;
import sun.net.www.*;
import sun.net.smtp.SmtpClient;
import sun.net.www.ParseUtil;
@ -65,7 +67,12 @@ public class MailToURLConnection extends URLConnection {
String getFromAddress() {
String str = System.getProperty("user.fromaddr");
if (str == null) {
str = System.getProperty("user.name");
// Perform the property security check for user.name
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPropertyAccess("user.name");
}
str = StaticProperty.userName();
if (str != null) {
String host = System.getProperty("mail.host");
if (host == null) {

View File

@ -44,6 +44,7 @@ import java.util.concurrent.ConcurrentHashMap;
import jdk.internal.misc.JavaSecurityAccess;
import static jdk.internal.misc.JavaSecurityAccess.ProtectionDomainCache;
import jdk.internal.misc.SharedSecrets;
import jdk.internal.util.StaticProperty;
import sun.security.util.*;
import sun.net.www.ParseUtil;
@ -279,7 +280,7 @@ public class PolicyFile extends java.security.Policy {
public URL run() {
String sep = File.separator;
try {
return Path.of(System.getProperty("java.home"),
return Path.of(StaticProperty.javaHome(),
"lib", "security",
"default.policy").toUri().toURL();
} catch (MalformedURLException mue) {

View File

@ -29,6 +29,8 @@ import java.io.*;
import java.net.*;
import java.util.Map;
import java.security.*;
import jdk.internal.util.StaticProperty;
import sun.security.action.GetPropertyAction;
/**
@ -403,7 +405,7 @@ final class SunEntries {
if(deviceURI.isOpaque()) {
// File constructor does not accept opaque URI
URI localDir = new File(
System.getProperty("user.dir")).toURI();
StaticProperty.userDir()).toURI();
String uriPath = localDir.toString() +
deviceURI.toString().substring(5);
return new File(URI.create(uriPath));

View File

@ -36,6 +36,7 @@ import java.util.Enumeration;
import java.util.HashSet;
import java.util.Set;
import jdk.internal.util.StaticProperty;
import sun.security.x509.X509CertImpl;
/**
@ -52,7 +53,7 @@ public class AnchorCertificates {
AccessController.doPrivileged(new PrivilegedAction<Void>() {
@Override
public Void run() {
File f = new File(System.getProperty("java.home"),
File f = new File(StaticProperty.javaHome(),
"lib/security/cacerts");
KeyStore cacerts;
try {

View File

@ -26,12 +26,12 @@ package sun.security.util;
import java.io.*;
import java.security.AccessController;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.PrivilegedAction;
import java.security.cert.X509Certificate;
import java.security.cert.CertificateException;
import java.util.*;
import jdk.internal.util.StaticProperty;
import sun.security.x509.X509CertImpl;
/**
@ -54,7 +54,7 @@ public final class UntrustedCertificates {
AccessController.doPrivileged(new PrivilegedAction<Void>() {
@Override
public Void run() {
File f = new File(System.getProperty("java.home"),
File f = new File(StaticProperty.javaHome(),
"lib/security/blacklisted.certs");
try (FileInputStream fin = new FileInputStream(f)) {
props.load(fin);

View File

@ -45,12 +45,11 @@ import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Set;
import java.util.SimpleTimeZone;
import java.util.concurrent.ConcurrentHashMap;
import java.util.zip.CRC32;
import jdk.internal.util.StaticProperty;
import sun.security.action.GetPropertyAction;
/**
@ -252,7 +251,7 @@ public final class ZoneInfoFile {
AccessController.doPrivileged(new PrivilegedAction<Void>() {
public Void run() {
try {
String libDir = System.getProperty("java.home") + File.separator + "lib";
String libDir = StaticProperty.javaHome() + File.separator + "lib";
try (DataInputStream dis = new DataInputStream(
new BufferedInputStream(new FileInputStream(
new File(libDir, "tzdb.dat"))))) {

View File

@ -29,6 +29,7 @@ import java.nio.file.*;
import java.nio.file.attribute.*;
import java.nio.file.spi.FileTypeDetector;
import java.io.IOException;
import jdk.internal.util.StaticProperty;
import sun.security.action.GetPropertyAction;
/**
@ -84,8 +85,7 @@ public class SolarisFileSystemProvider extends UnixFileSystemProvider {
@Override
FileTypeDetector getFileTypeDetector() {
Path userMimeTypes = Path.of(
GetPropertyAction.privilegedGetProperty("user.home"), ".mime.types");
Path userMimeTypes = Path.of(StaticProperty.userHome(), ".mime.types");
Path etcMimeTypes = Path.of("/etc/mime.types");
return chain(new MimeTypesFileTypeDetector(userMimeTypes),

View File

@ -26,6 +26,8 @@
package java.io;
import java.util.Properties;
import jdk.internal.util.StaticProperty;
import sun.security.action.GetPropertyAction;
@ -40,8 +42,8 @@ class UnixFileSystem extends FileSystem {
Properties props = GetPropertyAction.privilegedGetProperties();
slash = props.getProperty("file.separator").charAt(0);
colon = props.getProperty("path.separator").charAt(0);
javaHome = props.getProperty("java.home");
userDir = props.getProperty("user.dir");
javaHome = StaticProperty.javaHome();
userDir = StaticProperty.userDir();
}

View File

@ -49,6 +49,7 @@ import java.security.PrivilegedExceptionAction;
import java.util.Properties;
import jdk.internal.misc.JavaIOFileDescriptorAccess;
import jdk.internal.misc.SharedSecrets;
import jdk.internal.util.StaticProperty;
import sun.security.action.GetPropertyAction;
/**
@ -122,7 +123,7 @@ final class ProcessImpl extends Process {
String helperPath() {
Properties props = GetPropertyAction.privilegedGetProperties();
return helperPath(props.getProperty("java.home"),
return helperPath(StaticProperty.javaHome(),
props.getProperty("os.arch"));
}

View File

@ -25,6 +25,8 @@
package sun.nio.fs;
import jdk.internal.util.StaticProperty;
import java.nio.file.*;
import java.nio.file.attribute.*;
import java.nio.channels.*;
@ -259,7 +261,7 @@ abstract class UnixFileStore
private static Properties loadProperties() {
Properties result = new Properties();
String fstypes = System.getProperty("java.home") + "/lib/fstypes.properties";
String fstypes = StaticProperty.javaHome() + "/lib/fstypes.properties";
Path file = Path.of(fstypes);
try {
try (ReadableByteChannel rbc = Files.newByteChannel(file)) {

View File

@ -34,6 +34,7 @@ import java.io.*;
import java.util.*;
import java.security.AccessController;
import jdk.internal.misc.Unsafe;
import jdk.internal.util.StaticProperty;
import sun.nio.ch.ThreadPool;
import sun.security.util.SecurityConstants;
@ -46,11 +47,10 @@ public class WindowsFileSystemProvider
{
private static final Unsafe unsafe = Unsafe.getUnsafe();
private static final String USER_DIR = "user.dir";
private final WindowsFileSystem theFileSystem;
public WindowsFileSystemProvider() {
theFileSystem = new WindowsFileSystem(this, System.getProperty(USER_DIR));
theFileSystem = new WindowsFileSystem(this, StaticProperty.userDir());
}
@Override