8343981: Remove usage of security manager from Thread and related classes

Reviewed-by: rriggs, yzheng
This commit is contained in:
Alan Bateman 2024-11-13 18:49:31 +00:00
parent dbf23466af
commit 5e01c40b19
10 changed files with 54 additions and 282 deletions

View File

@ -47,7 +47,6 @@ import java.nio.channels.Channel;
import java.nio.channels.spi.SelectorProvider;
import java.nio.charset.CharacterCodingException;
import java.nio.charset.Charset;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.CodeSource;
import java.security.PrivilegedAction;
@ -2134,9 +2133,6 @@ public final class System {
public void registerShutdownHook(int slot, boolean registerShutdownInProgress, Runnable hook) {
Shutdown.add(slot, registerShutdownInProgress, hook);
}
public Thread newThreadWithAcc(Runnable target, @SuppressWarnings("removal") AccessControlContext acc) {
return new Thread(target, acc);
}
@SuppressWarnings("removal")
public void invokeFinalize(Object o) throws Throwable {
o.finalize();

View File

@ -27,9 +27,6 @@ package java.lang;
import java.lang.ref.Reference;
import java.lang.reflect.Field;
import java.security.AccessController;
import java.security.AccessControlContext;
import java.security.PrivilegedAction;
import java.time.Duration;
import java.util.Map;
import java.util.HashMap;
@ -41,8 +38,6 @@ import jdk.internal.event.ThreadSleepEvent;
import jdk.internal.misc.TerminatingThreadLocal;
import jdk.internal.misc.Unsafe;
import jdk.internal.misc.VM;
import jdk.internal.reflect.CallerSensitive;
import jdk.internal.reflect.Reflection;
import jdk.internal.vm.Continuation;
import jdk.internal.vm.ScopedValueContainer;
import jdk.internal.vm.StackableScope;
@ -52,7 +47,6 @@ import jdk.internal.vm.annotation.Hidden;
import jdk.internal.vm.annotation.IntrinsicCandidate;
import jdk.internal.vm.annotation.Stable;
import sun.nio.ch.Interruptible;
import sun.security.util.SecurityConstants;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.NANOSECONDS;
@ -652,21 +646,6 @@ public class Thread implements Runnable {
}
}
/**
* Returns the context class loader to inherit from the parent thread.
* See Thread initialization.
*/
private static ClassLoader contextClassLoader(Thread parent) {
@SuppressWarnings("removal")
SecurityManager sm = System.getSecurityManager();
if (sm == null || isCCLOverridden(parent.getClass())) {
return parent.getContextClassLoader();
} else {
// skip call to getContextClassLoader
return parent.contextClassLoader;
}
}
/**
* Initializes a platform Thread.
*
@ -676,11 +655,8 @@ public class Thread implements Runnable {
* @param task the object whose run() method gets called
* @param stackSize the desired stack size for the new thread, or
* zero to indicate that this parameter is to be ignored.
* @param acc ignored
*/
@SuppressWarnings("removal")
Thread(ThreadGroup g, String name, int characteristics, Runnable task,
long stackSize, AccessControlContext acc) {
Thread(ThreadGroup g, String name, int characteristics, Runnable task, long stackSize) {
Thread parent = currentThread();
boolean attached = (parent == this); // primordial or JNI attached
@ -691,27 +667,10 @@ public class Thread implements Runnable {
}
this.holder = new FieldHolder(g, task, stackSize, NORM_PRIORITY, false);
} else {
SecurityManager sm = System.getSecurityManager();
if (g == null) {
// the security manager can choose the thread group
if (sm != null) {
g = sm.getThreadGroup();
}
// default to current thread's group
if (g == null) {
g = parent.getThreadGroup();
}
g = parent.getThreadGroup();
}
// permission checks when creating a child Thread
if (sm != null) {
sm.checkAccess(g);
if (isCCLOverridden(getClass())) {
sm.checkPermission(SecurityConstants.SUBCLASS_IMPLEMENTATION_PERMISSION);
}
}
int priority = Math.min(parent.getPriority(), g.getMaxPriority());
this.holder = new FieldHolder(g, task, stackSize, priority, parent.isDaemon());
}
@ -732,7 +691,7 @@ public class Thread implements Runnable {
this.inheritableThreadLocals = ThreadLocal.createInheritedMap(parentMap);
}
if (VM.isBooted()) {
this.contextClassLoader = contextClassLoader(parent);
this.contextClassLoader = parent.getContextClassLoader();
}
} else if (VM.isBooted()) {
// default CCL to the system class loader when not inheriting
@ -763,7 +722,7 @@ public class Thread implements Runnable {
if (parentMap != null && parentMap.size() > 0) {
this.inheritableThreadLocals = ThreadLocal.createInheritedMap(parentMap);
}
this.contextClassLoader = contextClassLoader(parent);
this.contextClassLoader = parent.getContextClassLoader();
} else {
// default CCL to the system class loader when not inheriting
this.contextClassLoader = ClassLoader.getSystemClassLoader();
@ -1105,7 +1064,7 @@ public class Thread implements Runnable {
* @see <a href="#inheritance">Inheritance when creating threads</a>
*/
public Thread() {
this(null, null, 0, null, 0, null);
this(null, null, 0, null, 0);
}
/**
@ -1126,16 +1085,7 @@ public class Thread implements Runnable {
* @see <a href="#inheritance">Inheritance when creating threads</a>
*/
public Thread(Runnable task) {
this(null, null, 0, task, 0, null);
}
/**
* Creates a new Thread that inherits the given AccessControlContext
* but thread-local variables are not inherited.
* This is not a public constructor.
*/
Thread(Runnable task, @SuppressWarnings("removal") AccessControlContext acc) {
this(null, null, 0, task, 0, acc);
this(null, null, 0, task, 0);
}
/**
@ -1160,7 +1110,7 @@ public class Thread implements Runnable {
* @see <a href="#inheritance">Inheritance when creating threads</a>
*/
public Thread(ThreadGroup group, Runnable task) {
this(group, null, 0, task, 0, null);
this(group, null, 0, task, 0);
}
/**
@ -1177,7 +1127,7 @@ public class Thread implements Runnable {
* @see <a href="#inheritance">Inheritance when creating threads</a>
*/
public Thread(String name) {
this(null, checkName(name), 0, null, 0, null);
this(null, checkName(name), 0, null, 0);
}
/**
@ -1198,7 +1148,7 @@ public class Thread implements Runnable {
* @see <a href="#inheritance">Inheritance when creating threads</a>
*/
public Thread(ThreadGroup group, String name) {
this(group, checkName(name), 0, null, 0, null);
this(group, checkName(name), 0, null, 0);
}
/**
@ -1220,7 +1170,7 @@ public class Thread implements Runnable {
* @see <a href="#inheritance">Inheritance when creating threads</a>
*/
public Thread(Runnable task, String name) {
this(null, checkName(name), 0, task, 0, null);
this(null, checkName(name), 0, task, 0);
}
/**
@ -1256,7 +1206,7 @@ public class Thread implements Runnable {
* @see <a href="#inheritance">Inheritance when creating threads</a>
*/
public Thread(ThreadGroup group, Runnable task, String name) {
this(group, checkName(name), 0, task, 0, null);
this(group, checkName(name), 0, task, 0);
}
/**
@ -1330,7 +1280,7 @@ public class Thread implements Runnable {
* @see <a href="#inheritance">Inheritance when creating threads</a>
*/
public Thread(ThreadGroup group, Runnable task, String name, long stackSize) {
this(group, checkName(name), 0, task, stackSize, null);
this(group, checkName(name), 0, task, stackSize);
}
/**
@ -1390,7 +1340,7 @@ public class Thread implements Runnable {
long stackSize, boolean inheritInheritableThreadLocals) {
this(group, checkName(name),
(inheritInheritableThreadLocals ? 0 : NO_INHERIT_THREAD_LOCALS),
task, stackSize, null);
task, stackSize);
}
/**
@ -2140,18 +2090,8 @@ public class Thread implements Runnable {
*
* @since 1.2
*/
@CallerSensitive
public ClassLoader getContextClassLoader() {
ClassLoader cl = this.contextClassLoader;
if (cl == null)
return null;
@SuppressWarnings("removal")
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
Class<?> caller = Reflection.getCallerClass();
ClassLoader.checkClassLoaderPermission(cl, caller);
}
return cl;
return contextClassLoader;
}
/**
@ -2167,11 +2107,6 @@ public class Thread implements Runnable {
* @since 1.2
*/
public void setContextClassLoader(ClassLoader cl) {
@SuppressWarnings("removal")
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(new RuntimePermission("setContextClassLoader"));
}
contextClassLoader = cl;
}
@ -2220,12 +2155,6 @@ public class Thread implements Runnable {
*/
public StackTraceElement[] getStackTrace() {
if (this != Thread.currentThread()) {
// check for getStackTrace permission
@SuppressWarnings("removal")
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkPermission(SecurityConstants.GET_STACK_TRACE_PERMISSION);
}
// optimization so we do not call into the vm for threads that
// have not yet started or have terminated
if (!isAlive()) {
@ -2285,14 +2214,6 @@ public class Thread implements Runnable {
* @since 1.5
*/
public static Map<Thread, StackTraceElement[]> getAllStackTraces() {
// check for getStackTrace permission
@SuppressWarnings("removal")
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkPermission(SecurityConstants.GET_STACK_TRACE_PERMISSION);
security.checkPermission(SecurityConstants.MODIFY_THREADGROUP_PERMISSION);
}
// Get a snapshot of the list of all threads
Thread[] threads = getThreads();
StackTraceElement[][] traces = dumpThreads(threads);
@ -2307,64 +2228,6 @@ public class Thread implements Runnable {
return m;
}
/** cache of subclass security audit results */
private static class Caches {
/** cache of subclass security audit results */
static final ClassValue<Boolean> subclassAudits =
new ClassValue<>() {
@Override
protected Boolean computeValue(Class<?> type) {
return auditSubclass(type);
}
};
}
/**
* Verifies that this (possibly subclass) instance can be constructed
* without violating security constraints: the subclass must not override
* security-sensitive non-final methods, or else the
* "enableContextClassLoaderOverride" RuntimePermission is checked.
*/
private static boolean isCCLOverridden(Class<?> cl) {
if (cl == Thread.class)
return false;
return Caches.subclassAudits.get(cl);
}
/**
* Performs reflective checks on given subclass to verify that it doesn't
* override security-sensitive non-final methods. Returns true if the
* subclass overrides any of the methods, false otherwise.
*/
private static boolean auditSubclass(final Class<?> subcl) {
@SuppressWarnings("removal")
Boolean result = AccessController.doPrivileged(
new PrivilegedAction<>() {
public Boolean run() {
for (Class<?> cl = subcl;
cl != Thread.class;
cl = cl.getSuperclass())
{
try {
cl.getDeclaredMethod("getContextClassLoader", new Class<?>[0]);
return Boolean.TRUE;
} catch (NoSuchMethodException ex) {
}
try {
Class<?>[] params = {ClassLoader.class};
cl.getDeclaredMethod("setContextClassLoader", params);
return Boolean.TRUE;
} catch (NoSuchMethodException ex) {
}
}
return Boolean.FALSE;
}
}
);
return result.booleanValue();
}
/**
* Return an array of all live threads.
*/
@ -2603,12 +2466,6 @@ public class Thread implements Runnable {
* @since 1.5
*/
public static void setDefaultUncaughtExceptionHandler(UncaughtExceptionHandler ueh) {
@SuppressWarnings("removal")
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(
new RuntimePermission("setDefaultUncaughtExceptionHandler"));
}
defaultUncaughtExceptionHandler = ueh;
}
@ -2675,7 +2532,6 @@ public class Thread implements Runnable {
/**
* Holder class for constants.
*/
@SuppressWarnings("removal")
private static class Constants {
// Thread group for virtual threads.
static final ThreadGroup VTHREAD_GROUP;

View File

@ -179,7 +179,7 @@ class ThreadBuilders {
public Thread unstarted(Runnable task) {
Objects.requireNonNull(task);
String name = nextThreadName();
var thread = new Thread(group, name, characteristics(), task, stackSize, null);
var thread = new Thread(group, name, characteristics(), task, stackSize);
if (daemonChanged)
thread.daemon(daemon);
if (priority != 0)
@ -353,7 +353,7 @@ class ThreadBuilders {
public Thread newThread(Runnable task) {
Objects.requireNonNull(task);
String name = nextThreadName();
Thread thread = new Thread(group, name, characteristics(), task, stackSize, null);
Thread thread = new Thread(group, name, characteristics(), task, stackSize);
if (daemonChanged)
thread.daemon(daemon);
if (priority != 0)

View File

@ -24,8 +24,6 @@
*/
package java.lang;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Locale;
import java.util.Objects;
import java.util.concurrent.CountDownLatch;
@ -58,7 +56,6 @@ import jdk.internal.vm.annotation.JvmtiHideEvents;
import jdk.internal.vm.annotation.JvmtiMountTransition;
import jdk.internal.vm.annotation.ReservedStackAccess;
import sun.nio.ch.Interruptible;
import sun.security.action.GetPropertyAction;
import static java.util.concurrent.TimeUnit.*;
/**
@ -1013,7 +1010,6 @@ final class VirtualThread extends BaseVirtualThread {
}
@Override
@SuppressWarnings("removal")
public void interrupt() {
if (Thread.currentThread() != this) {
// if current thread is a virtual thread then prevent it from being
@ -1409,39 +1405,32 @@ final class VirtualThread extends BaseVirtualThread {
/**
* Creates the default ForkJoinPool scheduler.
*/
@SuppressWarnings("removal")
private static ForkJoinPool createDefaultScheduler() {
ForkJoinWorkerThreadFactory factory = pool -> {
PrivilegedAction<ForkJoinWorkerThread> pa = () -> new CarrierThread(pool);
return AccessController.doPrivileged(pa);
};
PrivilegedAction<ForkJoinPool> pa = () -> {
int parallelism, maxPoolSize, minRunnable;
String parallelismValue = System.getProperty("jdk.virtualThreadScheduler.parallelism");
String maxPoolSizeValue = System.getProperty("jdk.virtualThreadScheduler.maxPoolSize");
String minRunnableValue = System.getProperty("jdk.virtualThreadScheduler.minRunnable");
if (parallelismValue != null) {
parallelism = Integer.parseInt(parallelismValue);
} else {
parallelism = Runtime.getRuntime().availableProcessors();
}
if (maxPoolSizeValue != null) {
maxPoolSize = Integer.parseInt(maxPoolSizeValue);
parallelism = Integer.min(parallelism, maxPoolSize);
} else {
maxPoolSize = Integer.max(parallelism, 256);
}
if (minRunnableValue != null) {
minRunnable = Integer.parseInt(minRunnableValue);
} else {
minRunnable = Integer.max(parallelism / 2, 1);
}
Thread.UncaughtExceptionHandler handler = (t, e) -> { };
boolean asyncMode = true; // FIFO
return new ForkJoinPool(parallelism, factory, handler, asyncMode,
0, maxPoolSize, minRunnable, pool -> true, 30, SECONDS);
};
return AccessController.doPrivileged(pa);
ForkJoinWorkerThreadFactory factory = pool -> new CarrierThread(pool);
int parallelism, maxPoolSize, minRunnable;
String parallelismValue = System.getProperty("jdk.virtualThreadScheduler.parallelism");
String maxPoolSizeValue = System.getProperty("jdk.virtualThreadScheduler.maxPoolSize");
String minRunnableValue = System.getProperty("jdk.virtualThreadScheduler.minRunnable");
if (parallelismValue != null) {
parallelism = Integer.parseInt(parallelismValue);
} else {
parallelism = Runtime.getRuntime().availableProcessors();
}
if (maxPoolSizeValue != null) {
maxPoolSize = Integer.parseInt(maxPoolSizeValue);
parallelism = Integer.min(parallelism, maxPoolSize);
} else {
maxPoolSize = Integer.max(parallelism, 256);
}
if (minRunnableValue != null) {
minRunnable = Integer.parseInt(minRunnableValue);
} else {
minRunnable = Integer.max(parallelism / 2, 1);
}
Thread.UncaughtExceptionHandler handler = (t, e) -> { };
boolean asyncMode = true; // FIFO
return new ForkJoinPool(parallelism, factory, handler, asyncMode,
0, maxPoolSize, minRunnable, pool -> true, 30, SECONDS);
}
/**
@ -1458,7 +1447,7 @@ final class VirtualThread extends BaseVirtualThread {
*/
private static ScheduledExecutorService[] createDelayedTaskSchedulers() {
String propName = "jdk.virtualThreadScheduler.timerQueues";
String propValue = GetPropertyAction.privilegedGetProperty(propName);
String propValue = System.getProperty(propName);
int queueCount;
if (propValue != null) {
queueCount = Integer.parseInt(propValue);

View File

@ -144,12 +144,6 @@ public interface JavaLangAccess {
*/
void registerShutdownHook(int slot, boolean registerShutdownInProgress, Runnable hook);
/**
* Returns a new Thread with the given Runnable and an
* inherited AccessControlContext.
*/
Thread newThreadWithAcc(Runnable target, @SuppressWarnings("removal") AccessControlContext acc);
/**
* Invokes the finalize method of the given object.
*/

View File

@ -25,8 +25,6 @@
package jdk.internal.misc;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinWorkerThread;
import jdk.internal.access.JavaLangAccess;
@ -114,17 +112,12 @@ public class CarrierThread extends ForkJoinWorkerThread {
/**
* The thread group for the carrier threads.
*/
@SuppressWarnings("removal")
private static ThreadGroup carrierThreadGroup() {
return AccessController.doPrivileged(new PrivilegedAction<ThreadGroup>() {
public ThreadGroup run() {
ThreadGroup group = JLA.currentCarrierThread().getThreadGroup();
for (ThreadGroup p; (p = group.getParent()) != null; )
group = p;
var carrierThreadsGroup = new ThreadGroup(group, "CarrierThreads");
return carrierThreadsGroup;
}
});
ThreadGroup group = JLA.currentCarrierThread().getThreadGroup();
for (ThreadGroup p; (p = group.getParent()) != null; )
group = p;
var carrierThreadsGroup = new ThreadGroup(group, "CarrierThreads");
return carrierThreadsGroup;
}
/**

View File

@ -25,10 +25,6 @@
package jdk.internal.misc;
import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.ProtectionDomain;
import java.security.PrivilegedAction;
import java.util.concurrent.atomic.AtomicInteger;
/**
@ -69,18 +65,8 @@ public final class InnocuousThread extends Thread {
* set to the given priority.
*/
public static Thread newThread(String name, Runnable target, int priority) {
if (System.getSecurityManager() == null) {
return createThread(name, target, 0L,
ClassLoader.getSystemClassLoader(), priority);
}
return AccessController.doPrivileged(
new PrivilegedAction<Thread>() {
@Override
public Thread run() {
return createThread(name, target, 0L,
ClassLoader.getSystemClassLoader(), priority);
}
});
return createThread(name, target, 0L,
ClassLoader.getSystemClassLoader(), priority);
}
/**
@ -103,17 +89,7 @@ public final class InnocuousThread extends Thread {
* Thread priority is set to the given priority.
*/
public static Thread newSystemThread(String name, Runnable target, int priority) {
if (System.getSecurityManager() == null) {
return createThread(name, target, 0L, null, priority);
}
return AccessController.doPrivileged(
new PrivilegedAction<Thread>() {
@Override
public Thread run() {
return createThread(name, target, 0L,
null, priority);
}
});
return createThread(name, target, 0L, null, priority);
}
/**
@ -122,17 +98,7 @@ public final class InnocuousThread extends Thread {
*/
public static Thread newSystemThread(String name, Runnable target,
long stackSize, int priority) {
if (System.getSecurityManager() == null) {
return createThread(name, target, stackSize, null, priority);
}
return AccessController.doPrivileged(
new PrivilegedAction<Thread>() {
@Override
public Thread run() {
return createThread(name, target, 0L,
null, priority);
}
});
return createThread(name, target, stackSize, null, priority);
}
private static Thread createThread(String name, Runnable target, long stackSize,
@ -207,18 +173,7 @@ public final class InnocuousThread extends Thread {
break;
group = parent;
}
final ThreadGroup root = group;
if (System.getSecurityManager() == null) {
INNOCUOUSTHREADGROUP = new ThreadGroup(root, "InnocuousThreadGroup");
} else {
INNOCUOUSTHREADGROUP = AccessController.doPrivileged(
new PrivilegedAction<ThreadGroup>() {
@Override
public ThreadGroup run() {
return new ThreadGroup(root, "InnocuousThreadGroup");
}
});
}
INNOCUOUSTHREADGROUP = new ThreadGroup(group, "InnocuousThreadGroup");
} catch (Exception e) {
throw new Error(e);
}

View File

@ -165,7 +165,6 @@ module java.base {
java.desktop,
java.logging,
java.management,
java.naming,
java.rmi,
jdk.charsets,
jdk.jartool,

View File

@ -1,5 +1,5 @@
/*
* Copyright (c) 1999, 2022, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1999, 2024, 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,8 +25,6 @@
package com.sun.jndi.ldap;
import jdk.internal.access.SharedSecrets;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
@ -109,14 +107,8 @@ public final class VersionHelper {
return Class.forName(className, true, getContextClassLoader());
}
@SuppressWarnings("removal")
Thread createThread(Runnable r) {
AccessControlContext acc = AccessController.getContext();
// 4290486: doPrivileged is needed to create a thread in
// an environment that restricts "modifyThreadGroup".
PrivilegedAction<Thread> act =
() -> SharedSecrets.getJavaLangAccess().newThreadWithAcc(r, acc);
return AccessController.doPrivileged(act);
return new Thread(r);
}
@SuppressWarnings("removal")

View File

@ -73,7 +73,6 @@ public class CheckCSMs {
Set.of("java/io/ObjectStreamField#getType ()Ljava/lang/Class;",
"java/lang/Runtime#load (Ljava/lang/String;)V",
"java/lang/Runtime#loadLibrary (Ljava/lang/String;)V",
"java/lang/Thread#getContextClassLoader ()Ljava/lang/ClassLoader;",
"javax/sql/rowset/serial/SerialJavaObject#getFields ()[Ljava/lang/reflect/Field;"
);
@ -81,7 +80,6 @@ public class CheckCSMs {
// methods that takes an additional caller class parameter.
private static Set<String> UNSUPPORTED_VIRTUAL_METHODS =
Set.of("java/io/ObjectStreamField#getType (Ljava/lang/Class;)Ljava/lang/Class;",
"java/lang/Thread#getContextClassLoader (Ljava/lang/Class;)Ljava/lang/ClassLoader;",
"javax/sql/rowset/serial/SerialJavaObject#getFields (Ljava/lang/Class;)[Ljava/lang/reflect/Field;"
);