8297451: ProcessHandleImpl should assert privilege when modifying reaper thread

Reviewed-by: chegar, alanb
This commit is contained in:
Ryan Ernst 2022-11-26 20:04:59 +00:00 committed by Chris Hegarty
parent 99d3840d36
commit 50f9043c69
2 changed files with 36 additions and 7 deletions

View file

@ -100,7 +100,7 @@ final class ProcessHandleImpl implements ProcessHandle {
ThreadFactory threadFactory = grimReaper -> { ThreadFactory threadFactory = grimReaper -> {
Thread t = InnocuousThread.newSystemThread("process reaper", grimReaper, Thread t = InnocuousThread.newSystemThread("process reaper", grimReaper,
stackSize, Thread.MAX_PRIORITY); stackSize, Thread.MAX_PRIORITY);
t.setDaemon(true); privilegedThreadSetDaemon(t, true);
return t; return t;
}; };
@ -115,6 +115,22 @@ final class ProcessHandleImpl implements ProcessHandle {
} }
} }
@SuppressWarnings("removal")
private static void privilegedThreadSetName(Thread thread, String name) {
AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
thread.setName(name);
return null;
});
}
@SuppressWarnings("removal")
private static void privilegedThreadSetDaemon(Thread thread, boolean on) {
AccessController.doPrivileged((PrivilegedAction<Void>) () -> {
thread.setDaemon(on);
return null;
});
}
/** /**
* Returns a CompletableFuture that completes with process exit status when * Returns a CompletableFuture that completes with process exit status when
* the process completes. * the process completes.
@ -140,8 +156,9 @@ final class ProcessHandleImpl implements ProcessHandle {
processReaperExecutor.execute(new Runnable() { processReaperExecutor.execute(new Runnable() {
// Use inner class to avoid lambda stack overhead // Use inner class to avoid lambda stack overhead
public void run() { public void run() {
String threadName = Thread.currentThread().getName(); Thread t = Thread.currentThread();
Thread.currentThread().setName("process reaper (pid " + pid + ")"); String threadName = t.getName();
privilegedThreadSetName(t, "process reaper (pid " + pid + ")");
try { try {
int exitValue = waitForProcessExit0(pid, shouldReap); int exitValue = waitForProcessExit0(pid, shouldReap);
if (exitValue == NOT_A_CHILD) { if (exitValue == NOT_A_CHILD) {
@ -172,7 +189,7 @@ final class ProcessHandleImpl implements ProcessHandle {
completions.remove(pid, newCompletion); completions.remove(pid, newCompletion);
} finally { } finally {
// Restore thread name // Restore thread name
Thread.currentThread().setName(threadName); privilegedThreadSetName(t, threadName);
} }
} }
}); });

View file

@ -24,7 +24,7 @@
/* /*
* @test * @test
* @bug 6980747 * @bug 6980747 8297451
* @summary Check that Process-related classes have the proper * @summary Check that Process-related classes have the proper
* doPrivileged blocks, and can be initialized with an adversarial * doPrivileged blocks, and can be initialized with an adversarial
* security manager. * security manager.
@ -52,6 +52,17 @@ public class SecurityManagerClinit {
} }
} }
// Security manager that unconditionally performs Thread Modify Access checks.
@SuppressWarnings("removal")
private static class TMACSecurityManager extends SecurityManager {
static final RuntimePermission MODIFY_THREAD_PERMISSION =
new RuntimePermission("modifyThread");
@Override
public void checkAccess(Thread thread) {
checkPermission(MODIFY_THREAD_PERMISSION);
}
}
public static void main(String[] args) throws Throwable { public static void main(String[] args) throws Throwable {
String javaExe = String javaExe =
System.getProperty("java.home") + System.getProperty("java.home") +
@ -60,10 +71,11 @@ public class SecurityManagerClinit {
final SimplePolicy policy = final SimplePolicy policy =
new SimplePolicy new SimplePolicy
(new FilePermission("<<ALL FILES>>", "execute"), (new FilePermission("<<ALL FILES>>", "execute"),
new RuntimePermission("setSecurityManager")); new RuntimePermission("setSecurityManager"),
new RuntimePermission("modifyThread"));
Policy.setPolicy(policy); Policy.setPolicy(policy);
System.setSecurityManager(new SecurityManager()); System.setSecurityManager(new TMACSecurityManager());
try { try {
String[] cmd = { javaExe, "-version" }; String[] cmd = { javaExe, "-version" };