[concurrency-interest] ScheduledThreadPoolExecutor and shutdown permission check.

Gregg Wonderly gregg at cytetech.com
Wed Apr 30 09:25:52 EDT 2008

Joe Bowbeer wrote:
> On Tue, Apr 29, 2008 at 10:29 AM, Gregg Wonderly wrote:
>> I have a STPE that I use in an applet.  At applet shutdown, I'd like to shutdown
>>  the executor, but alas it requests a Permission check for a RuntimePermission
>>  that I don't have in an unsigned applet.  It seems kind of silly to demand this
>>  permission when no other thread management permission exist in the JDK for
>>  applets.  Am I missing something in consideration of this issue?
> Interesting.  So the exception is from TPE.shutdown() when it calls
> checkPermission?
>     private static final RuntimePermission shutdownPerm =
>         new RuntimePermission("modifyThread");
>     SecurityManager security = System.getSecurityManager();
>     if (security != null)
>         security.checkPermission(shutdownPerm);
> Before checking to see if the current thread can interrupt the workers
> -- even if none of the workers will actually be interrupted...
>     if (security != null) { // Check if caller can modify our threads
>         for (Worker w : workers)
>             security.checkAccess(w.thread);
>     }
> The rationale is here
>      * [ ... ] we must cooperate
>      * with the security manager (if present), which may implement
>      * policies that make more sense for operations on Threads
>      * than they do for ThreadPools. This requires 3 steps:
>      *
>      * 1. Making sure caller has permission to shut down threads
>      * in general (see shutdownPerm).
>      *
>      * 2. If (1) passes, making sure the caller is allowed to
>      * modify each of our threads. This might not be true even if
>      * first check passed, if the SecurityManager treats some
>      * threads specially. If this check passes, then we can try
>      * to set runState.
>      *
>      * 3. If both (1) and (2) pass, dealing with inconsistent
>      * security managers that allow checkAccess but then throw a
>      * SecurityException when interrupt() is invoked.  In this
>      * third case, because we have already set runState, we can
>      * only try to back out from the shutdown as cleanly as
>      * possible. Some workers may have been killed but we remain
>      * in non-shutdown state (which may entail tryTerminate from
>      * workerDone starting a new worker to maintain liveness.)
> What should it do?

The primary issue is that the STPE object reference is the key to being able to 
shut things down.  If I have a reference, I should be able to use all functions 
of the class, because I am running in the same JVM.  If I was allowed to 
create/start something without a permission, it sure seems like I should be able 
to stop it with the same level of authorization.  The reachability of Threads in 
my ThreadGroup, or in non-root ThreadGroups, is a different issue.  Sure, that 
path should be protected from random access without proper permissions.  But, if 
I have a reference to TPE, that is a non-global reference (except in some 
potential code designs with static instances that are reachable from all threads 
with the same class loader/path based visibility), I think it should really use 
doPrivileged() on my behalf, and override the asserted authorization I have to 
shut things down when I call shutdown.

I'd guess that perhaps someone is thinking of a statically allocated instance 
that might be "referenceable" from rogue code, but I don't know.  I just don't 
see how the classes behavior provides anything useful from a security control 
perspective, especially since this is an instance based mechanism not a static 
reference mechanism, where Permission checks can make a lot more sense.

Does anyone have a pointer to existing JVM classes, or a real scenario of where 
I might be able to get a reference to a STPE, or any TPE I guess, which I didn't 
create, and then should not be able to shut it down?  Those a the cases where a 
wrapped Permission check would apply, and a delegate class/method could provide 
that service instead of it being in the base class.

Gregg Wonderly

More information about the Concurrency-interest mailing list