Skip to content

Commit

Permalink
8292177: InitialSecurityProperty JFR event
Browse files Browse the repository at this point in the history
Reviewed-by: mbaesken
Backport-of: 8c40b7dc8cd7b6a6d0c9349b991e0e01b69349c3
  • Loading branch information
GoeLin committed Jan 4, 2023
1 parent c95dda4 commit 95f23f7
Show file tree
Hide file tree
Showing 12 changed files with 401 additions and 153 deletions.
19 changes: 19 additions & 0 deletions src/java.base/share/classes/java/security/Security.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import java.io.*;
import java.net.URL;

import jdk.internal.access.JavaSecurityPropertiesAccess;
import jdk.internal.event.EventHelper;
import jdk.internal.event.SecurityPropertyModificationEvent;
import jdk.internal.access.SharedSecrets;
Expand Down Expand Up @@ -63,6 +64,9 @@ public final class Security {
/* The java.security properties */
private static Properties props;

/* cache a copy for recording purposes */
private static Properties initialSecurityProperties;

// An element in the cache
private static class ProviderProperty {
String className;
Expand All @@ -81,6 +85,13 @@ public Void run() {
return null;
}
});
// Set up JavaSecurityPropertiesAccess in SharedSecrets
SharedSecrets.setJavaSecurityPropertiesAccess(new JavaSecurityPropertiesAccess() {
@Override
public Properties getInitialProperties() {
return initialSecurityProperties;
}
});
}

private static void initialize() {
Expand All @@ -106,6 +117,14 @@ private static void initialize() {
}
loadProps(null, extraPropFile, overrideAll);
}
initialSecurityProperties = (Properties) props.clone();
if (sdebug != null) {
for (String key : props.stringPropertyNames()) {
sdebug.println("Initial security property: " + key + "=" +
props.getProperty(key));
}
}

}

private static boolean loadProps(File masterFile, String extraPropFile, boolean overrideAll) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
* Copyright (c) 2022, 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.access;

import java.util.Properties;

public interface JavaSecurityPropertiesAccess {
Properties getInitialProperties();
}
15 changes: 15 additions & 0 deletions src/java.base/share/classes/jdk/internal/access/SharedSecrets.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
import java.io.ObjectInputFilter;
import java.lang.invoke.MethodHandles;
import java.lang.module.ModuleDescriptor;
import java.security.Security;
import java.security.spec.EncodedKeySpec;
import java.util.ResourceBundle;
import java.util.jar.JarFile;
Expand Down Expand Up @@ -77,6 +78,7 @@ public class SharedSecrets {
private static JavaUtilZipFileAccess javaUtilZipFileAccess;
private static JavaUtilResourceBundleAccess javaUtilResourceBundleAccess;
private static JavaSecurityAccess javaSecurityAccess;
private static JavaSecurityPropertiesAccess javaSecurityPropertiesAccess;
private static JavaSecuritySignatureAccess javaSecuritySignatureAccess;
private static JavaSecuritySpecAccess javaSecuritySpecAccess;
private static JavaxCryptoSealedObjectAccess javaxCryptoSealedObjectAccess;
Expand Down Expand Up @@ -283,6 +285,19 @@ public static JavaSecurityAccess getJavaSecurityAccess() {
return access;
}

public static void setJavaSecurityPropertiesAccess(JavaSecurityPropertiesAccess jspa) {
javaSecurityPropertiesAccess = jspa;
}

public static JavaSecurityPropertiesAccess getJavaSecurityPropertiesAccess() {
var access = javaSecurityPropertiesAccess;
if (access == null) {
ensureClassInitialized(Security.class);
access = javaSecurityPropertiesAccess;
}
return access;
}

public static JavaUtilZipFileAccess getJavaUtilZipFileAccess() {
var access = javaUtilZipFileAccess;
if (access == null) {
Expand Down
1 change: 1 addition & 0 deletions src/java.base/share/classes/module-info.java
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@
jdk.charsets,
jdk.jartool,
jdk.jlink,
jdk.jfr,
jdk.net,
jdk.incubator.foreign;
exports jdk.internal.access.foreign to
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* Copyright (c) 2022, 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.jfr.events;

import jdk.jfr.Category;
import jdk.jfr.Description;
import jdk.jfr.Label;
import jdk.jfr.Name;

@Category({"Java Development Kit", "Security"})
@Label("Initial Security Property")
@Name("jdk.InitialSecurityProperty")
@Description("Initial Security Properties")
public final class InitialSecurityPropertyEvent extends AbstractJDKEvent {
@Label("Key")
public String key;

@Label("Value")
public String value;
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import jdk.internal.access.SharedSecrets;
import jdk.jfr.Event;
import jdk.jfr.events.ActiveRecordingEvent;
import jdk.jfr.events.ActiveSettingEvent;
Expand All @@ -45,6 +47,7 @@
import jdk.jfr.events.FileReadEvent;
import jdk.jfr.events.FileWriteEvent;
import jdk.jfr.events.DeserializationEvent;
import jdk.jfr.events.InitialSecurityPropertyEvent;
import jdk.jfr.events.ProcessStartEvent;
import jdk.jfr.events.SecurityPropertyModificationEvent;
import jdk.jfr.events.SocketReadEvent;
Expand Down Expand Up @@ -90,7 +93,8 @@ public final class JDKEvents {
jdk.internal.event.X509CertificateEvent.class,
jdk.internal.event.X509ValidationEvent.class,

DirectBufferStatisticsEvent.class
DirectBufferStatisticsEvent.class,
InitialSecurityPropertyEvent.class,
};

// This is a list of the classes with instrumentation code that should be applied.
Expand All @@ -113,6 +117,7 @@ public final class JDKEvents {
private static final Runnable emitContainerCPUThrottling = JDKEvents::emitContainerCPUThrottling;
private static final Runnable emitContainerMemoryUsage = JDKEvents::emitContainerMemoryUsage;
private static final Runnable emitContainerIOUsage = JDKEvents::emitContainerIOUsage;
private static final Runnable emitInitialSecurityProperties = JDKEvents::emitInitialSecurityProperties;
private static Metrics containerMetrics = null;
private static boolean initializationTriggered;

Expand All @@ -129,6 +134,7 @@ public synchronized static void initialize() {

RequestEngine.addTrustedJDKHook(ExceptionStatisticsEvent.class, emitExceptionStatistics);
RequestEngine.addTrustedJDKHook(DirectBufferStatisticsEvent.class, emitDirectBufferStatistics);
RequestEngine.addTrustedJDKHook(InitialSecurityPropertyEvent.class, emitInitialSecurityProperties);

initializeContainerEvents();
initializationTriggered = true;
Expand Down Expand Up @@ -263,6 +269,7 @@ public static byte[] retransformCallback(Class<?> klass, byte[] oldBytes) throws
public static void remove() {
RequestEngine.removeHook(emitExceptionStatistics);
RequestEngine.removeHook(emitDirectBufferStatistics);
RequestEngine.removeHook(emitInitialSecurityProperties);

RequestEngine.removeHook(emitContainerConfiguration);
RequestEngine.removeHook(emitContainerCPUUsage);
Expand All @@ -275,4 +282,16 @@ private static void emitDirectBufferStatistics() {
DirectBufferStatisticsEvent e = new DirectBufferStatisticsEvent();
e.commit();
}

private static void emitInitialSecurityProperties() {
Properties p = SharedSecrets.getJavaSecurityPropertiesAccess().getInitialProperties();
if (p != null) {
for (String key : p.stringPropertyNames()) {
InitialSecurityPropertyEvent e = new InitialSecurityPropertyEvent();
e.key = key;
e.value = p.getProperty(key);
e.commit();
}
}
}
}
5 changes: 5 additions & 0 deletions src/jdk.jfr/share/conf/jfr/default.jfc
Original file line number Diff line number Diff line change
Expand Up @@ -705,6 +705,11 @@
<setting name="stackTrace">true</setting>
</event>

<event name="jdk.InitialSecurityProperty">
<setting name="enabled">true</setting>
<setting name="period">beginChunk</setting>
</event>

<event name="jdk.SecurityPropertyModification">
<setting name="enabled">false</setting>
<setting name="stackTrace">true</setting>
Expand Down
5 changes: 5 additions & 0 deletions src/jdk.jfr/share/conf/jfr/profile.jfc
Original file line number Diff line number Diff line change
Expand Up @@ -705,6 +705,11 @@
<setting name="stackTrace">true</setting>
</event>

<event name="jdk.InitialSecurityProperty">
<setting name="enabled">true</setting>
<setting name="period">beginChunk</setting>
</event>

<event name="jdk.SecurityPropertyModification">
<setting name="enabled">false</setting>
<setting name="stackTrace">true</setting>
Expand Down
32 changes: 30 additions & 2 deletions test/jdk/java/security/Security/ConfigFileTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,20 @@
/*
* @test
* @summary Throw error if default java.security file is missing
* @bug 8155246 8292297
* @bug 8155246 8292297 8292177
* @library /test/lib
* @run main ConfigFileTest
*/
public class ConfigFileTest {

private static final String EXPECTED_DEBUG_OUTPUT =
"Initial security property: crypto.policy=unlimited";

private static final String UNEXPECTED_DEBUG_OUTPUT =
"Initial security property: postInitTest=shouldNotRecord";

private static boolean overrideDetected = false;

public static void main(String[] args) throws Exception {
Path copyJdkDir = Path.of("./jdk-8155246-tmpdir");
Path copiedJava = Optional.of(
Expand All @@ -52,6 +60,7 @@ public static void main(String[] args) throws Exception {
if (args.length == 1) {
// set up is complete. Run code to exercise loading of java.security
Provider[] provs = Security.getProviders();
Security.setProperty("postInitTest", "shouldNotRecord");
System.out.println(Arrays.toString(provs) + "NumProviders: " + provs.length);
} else {
Files.createDirectory(copyJdkDir);
Expand Down Expand Up @@ -99,13 +108,32 @@ public static void main(String[] args) throws Exception {
copiedJava.toString(), "-cp", System.getProperty("test.classes"),
"-Djava.security.debug=all", "-Djavax.net.debug=all",
"-Djava.security.properties==file:///" + extraPropsFile, "ConfigFileTest", "runner");

if (!overrideDetected) {
throw new RuntimeException("Override scenario not seen");
}
}
}

private static void exerciseSecurity(int exitCode, String output, String... args) throws Exception {
ProcessBuilder process = new ProcessBuilder(args);
OutputAnalyzer oa = ProcessTools.executeProcess(process);
oa.shouldHaveExitValue(exitCode).shouldContain(output);
oa.shouldHaveExitValue(exitCode)
.shouldContain(output);

// extra checks on debug output
if (exitCode != 1) {
if (oa.getStderr().contains("overriding other security properties files!")) {
overrideDetected = true;
// master file is not in use - only provider properties are set in custom file
oa.shouldContain("security.provider.2=SunRsaSign")
.shouldNotContain(EXPECTED_DEBUG_OUTPUT)
.shouldNotContain(UNEXPECTED_DEBUG_OUTPUT);
} else {
oa.shouldContain(EXPECTED_DEBUG_OUTPUT)
.shouldNotContain(UNEXPECTED_DEBUG_OUTPUT);
}
}
}

private static void copyJDK(Path src, Path dst) throws Exception {
Expand Down
1 change: 1 addition & 0 deletions test/jdk/jdk/jfr/event/runtime/TestActiveSettingEvent.java
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,7 @@ private static void testSettingConfiguration(String configurationName) throws Ex
settingValues.put(EventNames.ActiveSetting + "#threshold", "0 ns");
settingValues.put(EventNames.ActiveRecording + "#stackTrace", "false");
settingValues.put(EventNames.ActiveRecording + "#threshold", "0 ns");
settingValues.put(EventNames.InitialSecurityProperty + "#threshold", "0 ns");
settingValues.put(EventNames.JavaExceptionThrow + "#threshold", "0 ns");
settingValues.put(EventNames.JavaErrorThrow + "#threshold", "0 ns");
settingValues.put(EventNames.SecurityProperty + "#threshold", "0 ns");
Expand Down
Loading

0 comments on commit 95f23f7

Please sign in to comment.