8249627: Degrade Thread.suspend and Thread.resume

Reviewed-by: cjplummer, sspitsyn, dholmes, jpai
This commit is contained in:
Alan Bateman 2022-09-27 11:43:59 +00:00
parent bc12e9553d
commit 1abf971b93
15 changed files with 113 additions and 232 deletions

View file

@ -1,5 +1,5 @@
/*
* Copyright (c) 1994, 2020, Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 1994, 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
@ -27,12 +27,9 @@ package java.lang;
/**
* Thrown to indicate that a thread is not in an appropriate state
* for the requested operation. See, for example, the
* {@code suspend} and {@code resume} methods in class
* {@code Thread}.
* for the requested operation.
*
* @see java.lang.Thread#resume()
* @see java.lang.Thread#suspend()
* @see Thread#start()
* @since 1.0
*/
public class IllegalThreadStateException extends IllegalArgumentException {

View file

@ -171,9 +171,8 @@ import java.lang.module.ModuleFinder;
* <tr>
* <th scope="row">modifyThread</th>
* <td>Modification of threads, e.g., via calls to Thread
* {@code interrupt, stop, suspend, resume, setDaemon, setPriority,
* setName} and {@code setUncaughtExceptionHandler}
* methods</td>
* {@code interrupt, setDaemon, setPriority, setName} and
* {@code setUncaughtExceptionHandler} methods</td>
* <td>This allows an attacker to modify the behaviour of
* any thread in the system.</td>
* </tr>
@ -181,9 +180,7 @@ import java.lang.module.ModuleFinder;
* <tr>
* <th scope="row">modifyThreadGroup</th>
* <td>modification of thread groups, e.g., via calls to ThreadGroup
* {@code destroy}, {@code getParent}, {@code resume},
* {@code setDaemon}, {@code setMaxPriority}, {@code stop},
* and {@code suspend} methods</td>
* {@code getParent}, {@code setDaemon}, and {@code setMaxPriority} methods</td>
* <td>This allows an attacker to create thread groups and
* set their run priority.</td>
* </tr>

View file

@ -494,7 +494,6 @@ public class SecurityManager {
* calling thread is not allowed to modify the thread argument.
* <p>
* This method is invoked for the current security manager by the
* {@code stop}, {@code suspend}, {@code resume},
* {@code setPriority}, {@code setName}, and
* {@code setDaemon} methods of class {@code Thread}.
* <p>
@ -523,12 +522,9 @@ public class SecurityManager {
* permission to modify the thread.
* @throws NullPointerException if the thread argument is
* {@code null}.
* @see java.lang.Thread#resume() resume
* @see java.lang.Thread#setDaemon(boolean) setDaemon
* @see java.lang.Thread#setName(java.lang.String) setName
* @see java.lang.Thread#setPriority(int) setPriority
* @see java.lang.Thread#stop() stop
* @see java.lang.Thread#suspend() suspend
* @see #checkPermission(java.security.Permission) checkPermission
*/
public void checkAccess(Thread t) {
@ -547,9 +543,8 @@ public class SecurityManager {
* <p>
* This method is invoked for the current security manager when a
* new child thread or child thread group is created, and by the
* {@code setDaemon}, {@code setMaxPriority},
* {@code stop}, {@code suspend}, {@code resume}, and
* {@code destroy} methods of class {@code ThreadGroup}.
* {@code setDaemon} and {@code setMaxPriority} methods of class
* {@code ThreadGroup}.
* <p>
* If the thread group argument is the system thread group (
* has a {@code null} parent) then
@ -576,12 +571,8 @@ public class SecurityManager {
* permission to modify the thread group.
* @throws NullPointerException if the thread group argument is
* {@code null}.
* @see java.lang.ThreadGroup#destroy() destroy
* @see java.lang.ThreadGroup#resume() resume
* @see java.lang.ThreadGroup#setDaemon(boolean) setDaemon
* @see java.lang.ThreadGroup#setMaxPriority(int) setMaxPriority
* @see java.lang.ThreadGroup#stop() stop
* @see java.lang.ThreadGroup#suspend() suspend
* @see #checkPermission(java.security.Permission) checkPermission
*/
public void checkAccess(ThreadGroup g) {

View file

@ -1798,65 +1798,41 @@ public class Thread implements Runnable {
private native boolean isAlive0();
/**
* Suspends this thread.
* <p>
* First, the {@code checkAccess} method of this thread is called
* with no arguments. This may result in throwing a
* {@code SecurityException} (in the current thread).
* <p>
* If the thread is alive, it is suspended and makes no further
* progress unless and until it is resumed.
* Throws {@code UnsupportedOperationException}.
*
* @throws SecurityException if the current thread cannot modify
* this thread.
* @throws UnsupportedOperationException if invoked on a virtual thread
* @see #checkAccess
* @deprecated This method has been deprecated, as it is
* inherently deadlock-prone. If the target thread holds a lock on the
* monitor protecting a critical system resource when it is suspended, no
* thread can access this resource until the target thread is resumed. If
* the thread that would resume the target thread attempts to lock this
* monitor prior to calling {@code resume}, deadlock results. Such
* deadlocks typically manifest themselves as "frozen" processes.
* For more information, see
* <a href="{@docRoot}/java.base/java/lang/doc-files/threadPrimitiveDeprecation.html">Why
* are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
* @throws UnsupportedOperationException always
*
* @deprecated This method was originally specified to suspend a thread.
* It was inherently deadlock-prone. If the target thread held a lock on
* a monitor protecting a critical system resource when it was suspended,
* no thread could access the resource until the target thread was resumed.
* If the thread intending to resume the target thread attempted to lock
* the monitor prior to calling {@code resume}, deadlock would result.
* Such deadlocks typically manifested themselves as "frozen" processes.
* For more information, see
* <a href="{@docRoot}/java.base/java/lang/doc-files/threadPrimitiveDeprecation.html">Why
* are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
*/
@Deprecated(since="1.2", forRemoval=true)
public final void suspend() {
checkAccess();
if (isVirtual())
throw new UnsupportedOperationException();
suspend0();
throw new UnsupportedOperationException();
}
/**
* Resumes a suspended thread.
* <p>
* First, the {@code checkAccess} method of this thread is called
* with no arguments. This may result in throwing a
* {@code SecurityException} (in the current thread).
* <p>
* If the thread is alive but suspended, it is resumed and is
* permitted to make progress in its execution.
* Throws {@code UnsupportedOperationException}.
*
* @throws SecurityException if the current thread cannot modify this
* thread.
* @throws UnsupportedOperationException if invoked on a virtual thread
* @see #checkAccess
* @see #suspend()
* @deprecated This method exists solely for use with {@link #suspend},
* which has been deprecated because it is deadlock-prone.
* @throws UnsupportedOperationException always
*
* @deprecated This method was originally specified to resume a thread
* suspended with {@link #suspend()}. Suspending a thread was
* inherently deadlock-prone.
* For more information, see
* <a href="{@docRoot}/java.base/java/lang/doc-files/threadPrimitiveDeprecation.html">Why
* are Thread.stop, Thread.suspend and Thread.resume Deprecated?</a>.
*/
@Deprecated(since="1.2", forRemoval=true)
public final void resume() {
checkAccess();
if (isVirtual())
throw new UnsupportedOperationException();
resume0();
throw new UnsupportedOperationException();
}
/**
@ -3035,8 +3011,6 @@ public class Thread implements Runnable {
/* Some private helper methods */
private native void setPriority0(int newPriority);
private native void suspend0();
private native void resume0();
private native void interrupt0();
private static native void clearInterruptEvent();
private native void setNativeName(String name);

View file

@ -160,13 +160,14 @@ operations for which thread.stop and thread.interrupt do not work
properly.</p>
<hr>
<h2>Why are <code>Thread.suspend</code> and
<code>Thread.resume</code> deprecated?</h2>
<p><code>Thread.suspend</code> is inherently deadlock-prone. If the
target thread holds a lock on the monitor protecting a critical
system resource when it is suspended, no thread can access this
resource until the target thread is resumed. If the thread that
would resume the target thread attempts to lock this monitor prior
to calling <code>resume</code>, deadlock results. Such deadlocks
<code>Thread.resume</code> deprecated and the ability to suspend or
resume a thread removed?</h2>
<p><code>Thread.suspend</code> was inherently deadlock-prone. If the
target thread held a lock on a monitor protecting a critical
system resource when it is suspended, no thread could access the
resource until the target thread was resumed. If the thread intending
to resume the target thread attempted to lock the monitor prior
to calling <code>resume</code>, deadlock resulted. Such deadlocks
typically manifest themselves as "frozen" processes.</p>
<hr>
<h2>What should I use instead of <code>Thread.suspend</code> and