[concurrency-interest] FutureTask.cancel(true) should run thread.interrupt within doPrivileged

Peter Levart peter.levart at gmail.com
Thu Oct 3 13:14:17 UTC 2013


On 10/02/2013 09:31 PM, Martin Buchholz wrote:
>> >Objection. I can straightaway see a way of getting an instance of a JDK-8
>> >FutureTask with a runner that is not current running the FutureTask.run,
>> >without so much as needing a race. That would allow an adversary to to
>> >interrupt a thread in contravention of the security policy.
> Interesting - FutureTask is designed to not make that possible - runner is
> not exposed, and is supposed to be set only while executing the task.  Do
> we have a bug?

Yes, the "bug" is in java.lang.Thread. Its inherent to the API for 
interrupt status handling. Thread has only one bit of information for 
interrupt status and one can not know whether the Thread.isInterrupted() 
== true is originating from Future.cancel(true) or some other legal 
interaction between the interrupted thread and some other interrupting 
thread. So FutureTask chooses not to clear the eventual interrupted 
status of the thread before it exits the run() method although it might 
have been interrupted by Future.cancel(true):

     /**
      * Ensures that any interrupt from a possible cancel(true) is only
      * delivered to a task while in run or runAndReset.
      */
     private void handlePossibleCancellationInterrupt(int s) {
         // It is possible for our interrupter to stall before getting a
         // chance to interrupt us.  Let's spin-wait patiently.
         if (s == INTERRUPTING)
             while (state == INTERRUPTING)
                 Thread.yield(); // wait out pending interrupt

         // assert state == INTERRUPTED;

         // We want to clear any interrupt we may have received from
         // cancel(true).  However, it is permissible to use interrupts
         // as an independent mechanism for a task to communicate with
         // its caller, and there is no way to clear only the
         // cancellation interrupt.
         //
         // Thread.interrupted();
     }

So the thread might be left in interrupted state after the task has 
finished it's run() method. But I don't think it's possible to interrupt 
some thread via FutureTask.cancel(true) unless that thread has 
"recently" been executing the task's run() method.

Regards, Peter




More information about the core-libs-dev mailing list