JDK-4254486 : interrupting dead applet thread throws security exception
  • Type: Bug
  • Component: other-libs
  • Sub-Component: other
  • Affected Version: 1.1.7,1.2.2,1.3.0
  • Priority: P4
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic,windows_98,windows_nt
  • CPU: generic,x86
  • Submitted: 1999-07-15
  • Updated: 2005-09-30
  • Resolved: 2005-09-30
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 6
6 b55Fixed
Related Reports
Duplicate :  
Relates :  
Relates :  
Description
Name: mc57594			Date: 07/15/99


This may be related to a jdk 1.1 Bug Id: 4031323
[chamness]
===================================================
In JDK 1.2, an applet was permitted to interrupt a thread that was no longer alive, but in JDK 1.2.1 and now in JDK 1.2.2, this raises a security exception. Perhaps this is an unintended side effect of the applet security bug-fix introduced in JDK 1.2.1?

I'm appending a simple test applet. The test is implemented in the button action: a 'waiter' thread first waits for a 'sleeper' thread to finish and then interrupts the sleeper thread. join() is used to wait for the sleeper to finish. Sure, ordinarily one wouldn't wait for a thread to finish and then interrupt it, but the test does this to demonstrate the problem:

C:\JOEB\JAVA\InterruptTest>appletviewer Test.html
java.security.AccessControlException: access denied (java.lang.RuntimePermission modifyThread )
        at java.security.AccessControlContext.checkPermission(AccessControlContext.java, Compiled Code)
        at java.security.AccessController.checkPermission(AccessController.java, Compiled Code)
        at java.lang.SecurityManager.checkPermission(SecurityManager.java, Compiled Code)
        at sun.applet.AppletSecurity.checkAccess(AppletSecurity.java:113)
        at java.lang.Thread.checkAccess(Thread.java:1043)
        at java.lang.Thread.interrupt(Thread.java:660)
        at Test$3.run(Test.java:35)
        at java.lang.Thread.run(Thread.java:479)

Note: If the join() is changed to join(1000), or removed entirely, there is no security exception because the sleeper thread will still be sleeping when it is interrupted. (But if the thread is already dead, then the attempt to interrupt throws a security exception..)

[Test.java]

import javax.swing.SwingUtilities;

public class Test extends javax.swing.JApplet {

  public Test() {
    getContentPane ().setLayout (new java.awt.BorderLayout ());
    jButton = new javax.swing.JButton ();
    jButton.setText ("Start");
    jButton.addActionListener (new java.awt.event.ActionListener () {
      public void actionPerformed (java.awt.event.ActionEvent evt) {
        jButtonActionPerformed (evt);
      }
    });
    getContentPane ().add (jButton, "Center");
  }

  private void jButtonActionPerformed (java.awt.event.ActionEvent evt) {

    final Thread sleeper = new Thread(new Runnable() {
      public void run() {
        try {
          Thread.sleep(3000);
        }
        catch (InterruptedException ex) { }
      }
    });

    Thread waiter = new Thread(new Runnable() {
      public void run() {
        try {
          sleeper.join();
        }
        catch (InterruptedException ex) { }
        sleeper.interrupt(); /* EXCEPTION */
        SwingUtilities.invokeLater(new Runnable() {
          public void run() {
            jButton.setEnabled(true);
          }
        });
      }
    });

    jButton.setEnabled(false);
    sleeper.start();
    waiter.start();

  }

  private javax.swing.JButton jButton;

}

[Test.html]

<HTML>
<HEAD><TITLE>Interrupt Test</TITLE></HEAD>
<BODY>
<APPLET code="Test.class" width=350 height=200></APPLET>
</BODY>
</HTML>
(Review ID: 85455) 
======================================================================

Comments
EVALUATION The AppletSecurity class' treatment of terminated threads will be made the same as java.lang.Security.checkAccess.
23-09-2005

SUGGESTED FIX The sun.applet.AppletSecurity.checkAccess method should use an approach similar to java.lang.SecurityManager.checkAccess such that a null group results in skipping the checkPermission call.
08-09-2005

EVALUATION This is caused by the fact that the current thread cannot modify a thread not in its thread group, but thread termination results in removal of a thread from its group (and subsequent use of getThreadGroup will return null). This constitutes a revocation of permission if mishandled. Although this case is handled properly by java.lang.Security.checkAccess, for applets sun.applet.AppletSecurity.checkAccess is used and this method fails to match up a thread's group because it is null.
08-09-2005

WORK AROUND Name: mc57594 Date: 07/15/99 Workarounds: (1) synchronize around the interrupt: synchronized(sleeper) { if (sleeper.isAlive()) { sleeper.interrupt(); } } (2) catch the security exception: try { sleeper.interrupt(); } catch (Exception ex) { } ======================================================================
11-06-2004

EVALUATION I agree with the reporter. This behavior is unpleasant. This will certainly be addressed as part of a future (1.5) project to overhaul thread specification and behavior. It may be worth fixing this one sooner. joshua.bloch@Eng 2001-01-23 Further reduction of the test case is needed to determine the exact cause of failure more precisely. In particular, we should be able to reproduce the problem even when not using any applet-related code. If one looks at AppletSecurity.checkAccess(), one can see that it bases its decision on whether to allow access on thread group membership and thread group relationships. Therefore there may be a bug in the handling of thread groups, and perhaps the bug is really in AppletSecurity, not in java/lang. Do dead threads leave their thread group? ###@###.### 2004-01-26
26-01-2004