Skip to content
Permalink
Browse files

Automatic merge of jdk:master into master

  • Loading branch information
duke
duke committed Jul 8, 2020
2 parents 44668e5 + 4d2b0b5 commit 35607d13683ddc1fdd7fc3d34514babe7e3dc0e8
@@ -354,6 +354,7 @@ $(MODULE_DEPS_MAKEFILE): $(MODULE_INFOS) \
sub(/\/\*.*\*\//, ""); \
gsub(/^ +\*.*/, ""); \
gsub(/ /, ""); \
gsub(/\r/, ""); \
printf(" %s", $$0) } \
END { printf("\n") }' $m && \
$(PRINTF) "TRANSITIVE_MODULES_$(call GetModuleNameFromModuleInfo, $m) :=" && \
@@ -367,6 +368,7 @@ $(MODULE_DEPS_MAKEFILE): $(MODULE_INFOS) \
sub(/\/\*.*\*\//, ""); \
gsub(/^ +\*.*/, ""); \
gsub(/ /, ""); \
gsub(/\r/, ""); \
printf(" %s", $$0) } \
END { printf("\n") }' $m \
) >> $@ $(NEWLINE))
@@ -67,6 +67,8 @@
* Returns the field with the specified name, or {@code null} if it doesn't
* exist.
*
* @param name of the field to get, not {@code null}
*
* @return a value descriptor that describes the field, or {@code null} if
* the field with the specified name doesn't exist
*/
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2016, 2020, 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
@@ -25,6 +25,7 @@

package jdk.jfr;

import java.security.AccessControlContext;
import java.util.Collections;
import java.util.List;
import java.util.Map;
@@ -191,6 +192,11 @@ public boolean isUnsigned(ValueDescriptor v) {
public PlatformRecorder getPlatformRecorder() {
return FlightRecorder.getFlightRecorder().getInternal();
}

@Override
public AccessControlContext getContext(SettingControl settingControl) {
return settingControl.getContext();
}
}

/**
@@ -25,10 +25,11 @@

package jdk.jfr;

import java.security.AccessControlContext;
import java.security.AccessController;
import java.util.Set;

import jdk.jfr.internal.Control;
import jdk.jfr.internal.settings.JDKSettingControl;

/**
* Base class to extend to create setting controls.
@@ -139,14 +140,29 @@
* @since 9
*/
@MetadataDefinition
public abstract class SettingControl extends Control {
public abstract class SettingControl {

private final AccessControlContext context;
private final boolean initialized;

/**
* Constructor for invocation by subclass constructors.
*/
protected SettingControl() {
super(AccessController.getContext());
context = this instanceof JDKSettingControl ? null : AccessController.getContext();
initialized = true;
}

final AccessControlContext getContext() {
// Ensure object state is safe
if (!initialized) {
throw new InternalError("Object must be initialized before security context can be retrieved");
}
AccessControlContext c = this.context;
if (c == null && !(this instanceof JDKSettingControl)) {
throw new InternalError("Security context can only be null for trusted setting controls");
}
return c;
}

/**
@@ -181,7 +197,6 @@ protected SettingControl() {
*
* @return the value to use, not {@code null}
*/
@Override
public abstract String combine(Set<String> settingValues);

/**
@@ -192,7 +207,6 @@ protected SettingControl() {
*
* @param settingValue the string value, not {@code null}
*/
@Override
public abstract void setValue(String settingValue);

/**
@@ -208,6 +222,5 @@ protected SettingControl() {
*
* @return the setting value, not {@code null}
*/
@Override
public abstract String getValue();
}
@@ -120,7 +120,7 @@ public Duration getDuration() {
return objectContext.fields;
}

protected final Object objectAt(int index) {
final Object objectAt(int index) {
if (index == 0) {
return startTimeTicks;
}
@@ -254,7 +254,7 @@ public boolean hasField(String name) {
return t;
}

protected Object objectAt(int index) {
Object objectAt(int index) {
return objects[index];
}

@@ -25,9 +25,6 @@

package jdk.jfr.internal;

import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.PrivilegedAction;
@@ -36,61 +33,44 @@
import java.util.Objects;
import java.util.Set;

// User must never be able to subclass directly.
//
// Never put Control or Setting Control in a collections
// so overridable versions of hashCode or equals are
// executed in the wrong context. TODO: wrap this class
// in SsecureControl directly when it is instantiated and
// forward calls using AccessControlContext
abstract public class Control {
import jdk.jfr.SettingControl;
import jdk.jfr.internal.settings.JDKSettingControl;

public final class Control {
private final AccessControlContext context;
private final static int CACHE_SIZE = 5;
private final Set<?>[] cachedUnions = new HashSet<?>[CACHE_SIZE];
private final String[] cachedValues = new String[CACHE_SIZE];
private final SettingControl delegate;
private String defaultValue;
private String lastValue;

// called by exposed subclass in external API
public Control(AccessControlContext acc) {
Objects.requireNonNull(acc);
this.context = acc;

}

// only to be called by trusted VM code
public Control(String defaultValue) {
public Control(SettingControl delegate, String defaultValue) {
this.context = PrivateAccess.getInstance().getContext(delegate);
this.delegate = delegate;
this.defaultValue = defaultValue;
this.context = null;
if (this.context == null && !(delegate instanceof JDKSettingControl)) {
throw new InternalError("Security context can only be null for trusted setting controls");
}
}

// For user code to override, must never be called from jdk.jfr.internal
// for user defined settings
public abstract String combine(Set<String> values);

// For user code to override, must never be called from jdk.jfr.internal
// for user defined settings
public abstract void setValue(String value);

// For user code to override, must never be called from jdk.jfr.internal
// for user defined settings
public abstract String getValue();
boolean isType(Class<? extends SettingControl> clazz) {
return delegate.getClass() == clazz;
}

// Package private, user code should not have access to this method
final void apply(Set<String> values) {
setValueSafe(findCombineSafe(values));
setValue(findCombine(values));
}

// Package private, user code should not have access to this method.
// Only called during event registration
final void setDefault() {
if (defaultValue == null) {
defaultValue = getValueSafe();
defaultValue = getValue();
}
apply(defaultValue);
}

final String getValueSafe() {
public String getValue() {
if (context == null) {
// VM events requires no access control context
return getValue();
@@ -99,7 +79,7 @@ final String getValueSafe() {
@Override
public String run() {
try {
return getValue();
return delegate.getValue();
} catch (Throwable t) {
// Prevent malicious user to propagate exception callback in the wrong context
Logger.log(LogTag.JFR_SETTING, LogLevel.WARN, "Exception occurred when trying to get value for " + getClass());
@@ -114,14 +94,14 @@ private void apply(String value) {
if (lastValue != null && Objects.equals(value, lastValue)) {
return;
}
setValueSafe(value);
setValue(value);
}

final void setValueSafe(String value) {
public void setValue(String value) {
if (context == null) {
// VM events requires no access control context
try {
setValue(value);
delegate.setValue(value);
} catch (Throwable t) {
Logger.log(LogTag.JFR_SETTING, LogLevel.WARN, "Exception occurred when setting value \"" + value + "\" for " + getClass());
}
@@ -130,7 +110,7 @@ final void setValueSafe(String value) {
@Override
public Void run() {
try {
setValue(value);
delegate.setValue(value);
} catch (Throwable t) {
// Prevent malicious user to propagate exception callback in the wrong context
Logger.log(LogTag.JFR_SETTING, LogLevel.WARN, "Exception occurred when setting value \"" + value + "\" for " + getClass());
@@ -143,16 +123,16 @@ public Void run() {
}


private String combineSafe(Set<String> values) {
public String combine(Set<String> values) {
if (context == null) {
// VM events requires no access control context
return combine(values);
return delegate.combine(values);
}
return AccessController.doPrivileged(new PrivilegedAction<String>() {
@Override
public String run() {
try {
combine(Collections.unmodifiableSet(values));
delegate.combine(Collections.unmodifiableSet(values));
} catch (Throwable t) {
// Prevent malicious user to propagate exception callback in the wrong context
Logger.log(LogTag.JFR_SETTING, LogLevel.WARN, "Exception occurred when combining " + values + " for " + getClass());
@@ -162,7 +142,7 @@ public String run() {
}, context);
}

private final String findCombineSafe(Set<String> values) {
private final String findCombine(Set<String> values) {
if (values.size() == 1) {
return values.iterator().next();
}
@@ -171,7 +151,7 @@ private final String findCombineSafe(Set<String> values) {
return cachedValues[i];
}
}
String result = combineSafe(values);
String result = combine(values);
for (int i = 0; i < CACHE_SIZE - 1; i++) {
cachedUnions[i + 1] = cachedUnions[i];
cachedValues[i + 1] = cachedValues[i];
@@ -181,29 +161,11 @@ private final String findCombineSafe(Set<String> values) {
return result;
}


// package private, user code should not have access to this method
final String getDefaultValue() {
return defaultValue;
}

// package private, user code should not have access to this method
final String getLastValue() {
return lastValue;
}

// Precaution to prevent a malicious user from instantiating instances
// of a control where the context has not been set up.
@Override
public final Object clone() throws java.lang.CloneNotSupportedException {
throw new CloneNotSupportedException();
}

private final void writeObject(ObjectOutputStream out) throws IOException {
throw new IOException("Object cannot be serialized");
}

private final void readObject(ObjectInputStream in) throws IOException {
throw new IOException("Class cannot be deserialized");
}
}

0 comments on commit 35607d1

Please sign in to comment.