You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@logging.apache.org by pk...@apache.org on 2022/09/02 23:10:48 UTC
[logging-log4j2] 01/02: LOG4J2-3579 Calls ServiceLoader with caller's security context
This is an automated email from the ASF dual-hosted git repository.
pkarwasz pushed a commit to branch release-2.x
in repository https://gitbox.apache.org/repos/asf/logging-log4j2.git
commit 880acdfdb0b3c13c73c9ab3375924e238814f948
Author: Piotr P. Karwasz <pi...@karwasz.org>
AuthorDate: Sun Aug 21 22:00:48 2022 +0200
LOG4J2-3579 Calls ServiceLoader with caller's security context
When running with a security manager, `ServiceLoaderUtil` will call
`ServiceLoader` with the privileges of the caller.
---
.../logging/log4j/util/ServiceLoaderUtil.java | 32 ++++++++++++++++++----
.../logging/log4j/util/ServiceLoaderUtil.java | 32 ++++++++++++++++++----
2 files changed, 52 insertions(+), 12 deletions(-)
diff --git a/log4j-api-java9/src/main/java/org/apache/logging/log4j/util/ServiceLoaderUtil.java b/log4j-api-java9/src/main/java/org/apache/logging/log4j/util/ServiceLoaderUtil.java
index 9450e539a8..10b8cd547d 100644
--- a/log4j-api-java9/src/main/java/org/apache/logging/log4j/util/ServiceLoaderUtil.java
+++ b/log4j-api-java9/src/main/java/org/apache/logging/log4j/util/ServiceLoaderUtil.java
@@ -17,10 +17,13 @@
package org.apache.logging.log4j.util;
+import java.lang.invoke.CallSite;
+import java.lang.invoke.LambdaMetafactory;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles.Lookup;
import java.lang.invoke.MethodType;
-import java.util.Arrays;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
import java.util.HashSet;
import java.util.Objects;
import java.util.ServiceConfigurationError;
@@ -32,9 +35,6 @@ import org.apache.logging.log4j.status.StatusLogger;
public final class ServiceLoaderUtil {
- private static final MethodType LOAD_CLASS_CLASSLOADER = MethodType.methodType(ServiceLoader.class, Class.class,
- ClassLoader.class);
-
private ServiceLoaderUtil() {
}
@@ -87,8 +87,28 @@ public final class ServiceLoaderUtil {
static <T> Stream<T> loadClassloaderServices(final Class<T> serviceType, final Lookup lookup,
final ClassLoader classLoader, final boolean verbose) {
try {
- final MethodHandle handle = lookup.findStatic(ServiceLoader.class, "load", LOAD_CLASS_CLASSLOADER);
- final ServiceLoader<T> serviceLoader = (ServiceLoader<T>) handle.invokeExact(serviceType, classLoader);
+ // Creates a lambda in the caller's domain that calls `ServiceLoader`
+ final MethodHandle loadHandle = lookup.findStatic(ServiceLoader.class, "load",
+ MethodType.methodType(ServiceLoader.class, Class.class, ClassLoader.class));
+ final CallSite callSite = LambdaMetafactory.metafactory(lookup,
+ "run",
+ MethodType.methodType(PrivilegedAction.class, Class.class, ClassLoader.class),
+ MethodType.methodType(Object.class),
+ loadHandle,
+ MethodType.methodType(ServiceLoader.class));
+ final PrivilegedAction<ServiceLoader<T>> action = (PrivilegedAction<ServiceLoader<T>>) callSite
+ .getTarget()//
+ .bindTo(serviceType)
+ .bindTo(classLoader)
+ .invoke();
+ final ServiceLoader<T> serviceLoader;
+ if (System.getSecurityManager() == null) {
+ serviceLoader = action.run();
+ } else {
+ final MethodHandle privilegedHandle = lookup.findStatic(AccessController.class, "doPrivileged",
+ MethodType.methodType(Object.class, PrivilegedAction.class));
+ serviceLoader = (ServiceLoader<T>) privilegedHandle.invoke(action);
+ }
return serviceLoader.stream().map(provider -> {
try {
return provider.get();
diff --git a/log4j-api/src/main/java/org/apache/logging/log4j/util/ServiceLoaderUtil.java b/log4j-api/src/main/java/org/apache/logging/log4j/util/ServiceLoaderUtil.java
index ab2ddd3934..0230bf403b 100644
--- a/log4j-api/src/main/java/org/apache/logging/log4j/util/ServiceLoaderUtil.java
+++ b/log4j-api/src/main/java/org/apache/logging/log4j/util/ServiceLoaderUtil.java
@@ -17,9 +17,13 @@
package org.apache.logging.log4j.util;
+import java.lang.invoke.CallSite;
+import java.lang.invoke.LambdaMetafactory;
import java.lang.invoke.MethodHandle;
import java.lang.invoke.MethodHandles.Lookup;
import java.lang.invoke.MethodType;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
@@ -39,9 +43,6 @@ import org.apache.logging.log4j.status.StatusLogger;
*/
public final class ServiceLoaderUtil {
- private static final MethodType LOAD_CLASS_CLASSLOADER = MethodType.methodType(ServiceLoader.class, Class.class,
- ClassLoader.class);
-
private ServiceLoaderUtil() {
}
@@ -102,8 +103,28 @@ public final class ServiceLoaderUtil {
static <T> Iterable<T> callServiceLoader(Lookup lookup, Class<T> serviceType, ClassLoader classLoader,
boolean verbose) {
try {
- final MethodHandle handle = lookup.findStatic(ServiceLoader.class, "load", LOAD_CLASS_CLASSLOADER);
- final ServiceLoader<T> serviceLoader = (ServiceLoader<T>) handle.invokeExact(serviceType, classLoader);
+ // Creates a lambda in the caller's domain that calls `ServiceLoader`
+ final MethodHandle loadHandle = lookup.findStatic(ServiceLoader.class, "load",
+ MethodType.methodType(ServiceLoader.class, Class.class, ClassLoader.class));
+ final CallSite callSite = LambdaMetafactory.metafactory(lookup,
+ "run",
+ MethodType.methodType(PrivilegedAction.class, Class.class, ClassLoader.class),
+ MethodType.methodType(Object.class),
+ loadHandle,
+ MethodType.methodType(ServiceLoader.class));
+ final PrivilegedAction<ServiceLoader<T>> action = (PrivilegedAction<ServiceLoader<T>>) callSite
+ .getTarget()//
+ .bindTo(serviceType)
+ .bindTo(classLoader)
+ .invoke();
+ final ServiceLoader<T> serviceLoader;
+ if (System.getSecurityManager() == null) {
+ serviceLoader = action.run();
+ } else {
+ final MethodHandle privilegedHandle = lookup.findStatic(AccessController.class, "doPrivileged",
+ MethodType.methodType(Object.class, PrivilegedAction.class));
+ serviceLoader = (ServiceLoader<T>) privilegedHandle.invoke(action);
+ }
return serviceLoader;
} catch (Throwable e) {
if (verbose) {
@@ -111,7 +132,6 @@ public final class ServiceLoaderUtil {
}
}
return Collections.emptyList();
-
}
private static class ServiceLoaderSpliterator<S> implements Spliterator<S> {