-
Bug
-
Resolution: Fixed
-
P3
-
9, 10, 11, 12, 13, 14, 15
Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-8305991 | 11.0.20-oracle | Joe Cherian | P3 | Resolved | Fixed | b02 |
JDK-8308106 | 11.0.20 | Lutz Schmidt | P3 | Resolved | Fixed | b03 |
The SystemProperty code used for VM argument parsing was reworked in Java 9 as part of the module system updates. In Java 8 the set_value() method was defined as follows:
bool set_value(char *value) {
if (writeable()) {
if (_value != NULL) {
FreeHeap(_value);
}
_value = AllocateHeap(strlen(value)+1, mtInternal);
if (_value != NULL) {
strcpy(_value, value);
}
return true;
}
return false;
}
so we can only update a writeable flag.
In Java 9 this was refactored so that SystemProperty extends PathString, which contains a simple set_value method that always sets the value:
bool PathString::set_value(const char *value) {
if (_value != NULL) {
FreeHeap(_value);
}
_value = AllocateHeap(strlen(value)+1, mtArguments);
assert(_value != NULL, "Unable to allocate space for new path value");
if (_value != NULL) {
strcpy(_value, value);
} else {
// not able to allocate
return false;
}
return true;
}
and SystemProperty added a new method:
// A system property should only have its value set
// via an external interface if it is a writeable property.
// The internal, non-writeable property jdk.boot.class.path.append
// is the only exception to this rule. It can be set externally
// via -Xbootclasspath/a or JVMTI OnLoad phase call to AddToBootstrapClassLoaderSearch.
// In those cases for jdk.boot.class.path.append, the base class
// set_value and append_value methods are called directly.
bool set_writeable_value(const char *value) {
if (writeable()) {
return set_value(value);
}
return false;
}
The intent was obviously that in general set_writeable_value should be used to attempt to set the value, but the general property handling code was not updated:
// This add maintains unique property key in the list.
void Arguments::PropertyList_unique_add(SystemProperty** plist, const char* k, const char* v,
PropertyAppendable append, PropertyWriteable writeable,
PropertyInternal internal) {
if (plist == NULL)
return;
// If property key exist then update with new value.
SystemProperty* prop;
for (prop = *plist; prop != NULL; prop = prop->next()) {
if (strcmp(k, prop->key()) == 0) {
if (append == AppendProperty) {
prop->append_value(v);
} else {
prop->set_value(v);
}
return;
}
}
PropertyList_add(plist, k, v, writeable == WriteableProperty, internal == InternalProperty);
}
Consequently whether the flag is writeable or not is ignored and it will always be appended or set. As a result the user can override non-writable system properties on the command-line e.g:
public class JavaProps {
public static void main(String[] args) {
System.out.println(System.getProperty(args[0]));
}
}
> java9 JavaProps java.vm.name
Java HotSpot(TM) 64-Bit Server VM
> java9 -Djava.vm.name=MyVM JavaProps java.vm.name
MyVM
Property was re-defined by the user! Whereas in Java 8:
> java JavaProps java.vm.name
OpenJDK 64-Bit Server VM
> java -Djava.vm.name=MyVM JavaProps java.vm.name
OpenJDK 64-Bit Server VM
bool set_value(char *value) {
if (writeable()) {
if (_value != NULL) {
FreeHeap(_value);
}
_value = AllocateHeap(strlen(value)+1, mtInternal);
if (_value != NULL) {
strcpy(_value, value);
}
return true;
}
return false;
}
so we can only update a writeable flag.
In Java 9 this was refactored so that SystemProperty extends PathString, which contains a simple set_value method that always sets the value:
bool PathString::set_value(const char *value) {
if (_value != NULL) {
FreeHeap(_value);
}
_value = AllocateHeap(strlen(value)+1, mtArguments);
assert(_value != NULL, "Unable to allocate space for new path value");
if (_value != NULL) {
strcpy(_value, value);
} else {
// not able to allocate
return false;
}
return true;
}
and SystemProperty added a new method:
// A system property should only have its value set
// via an external interface if it is a writeable property.
// The internal, non-writeable property jdk.boot.class.path.append
// is the only exception to this rule. It can be set externally
// via -Xbootclasspath/a or JVMTI OnLoad phase call to AddToBootstrapClassLoaderSearch.
// In those cases for jdk.boot.class.path.append, the base class
// set_value and append_value methods are called directly.
bool set_writeable_value(const char *value) {
if (writeable()) {
return set_value(value);
}
return false;
}
The intent was obviously that in general set_writeable_value should be used to attempt to set the value, but the general property handling code was not updated:
// This add maintains unique property key in the list.
void Arguments::PropertyList_unique_add(SystemProperty** plist, const char* k, const char* v,
PropertyAppendable append, PropertyWriteable writeable,
PropertyInternal internal) {
if (plist == NULL)
return;
// If property key exist then update with new value.
SystemProperty* prop;
for (prop = *plist; prop != NULL; prop = prop->next()) {
if (strcmp(k, prop->key()) == 0) {
if (append == AppendProperty) {
prop->append_value(v);
} else {
prop->set_value(v);
}
return;
}
}
PropertyList_add(plist, k, v, writeable == WriteableProperty, internal == InternalProperty);
}
Consequently whether the flag is writeable or not is ignored and it will always be appended or set. As a result the user can override non-writable system properties on the command-line e.g:
public class JavaProps {
public static void main(String[] args) {
System.out.println(System.getProperty(args[0]));
}
}
> java9 JavaProps java.vm.name
Java HotSpot(TM) 64-Bit Server VM
> java9 -Djava.vm.name=MyVM JavaProps java.vm.name
MyVM
Property was re-defined by the user! Whereas in Java 8:
> java JavaProps java.vm.name
OpenJDK 64-Bit Server VM
> java -Djava.vm.name=MyVM JavaProps java.vm.name
OpenJDK 64-Bit Server VM
- backported by
-
JDK-8305991 NonWriteable system properties are actually writeable
- Resolved
-
JDK-8308106 NonWriteable system properties are actually writeable
- Resolved
- blocks
-
JDK-8241071 Generation of classes.jsa with -Xshare:dump is not deterministic
- Resolved
- relates to
-
JDK-8136930 Simplify use of module-system options by custom launchers
- Resolved
-
JDK-8142968 Module System implementation
- Closed
(2 links to)