Bug 61568 - [Security Manager] InnocuousThread raises SecurityException on HTTP requests
Summary: [Security Manager] InnocuousThread raises SecurityException on HTTP requests
Status: RESOLVED FIXED
Alias: None
Product: Tomcat 8
Classification: Unclassified
Component: Catalina (show other bugs)
Version: 8.5.20
Hardware: PC Linux
: P2 normal (vote)
Target Milestone: ----
Assignee: Tomcat Developers Mailing List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-09-27 14:56 UTC by 1ax
Modified: 2017-10-06 13:37 UTC (History)
0 users



Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description 1ax 2017-09-27 14:56:00 UTC
I am running two webapps with two servlets on my server with security manager enabled. When manually testing the servlets, they respond just fine to HTTP post and get requests. When stress testing (e.g. multiple simultaneous requests) some requests fail (<1%) and raise the exception pasted below. When adding the permission java.security.AllPermission to the webapps, the exception still occurs. Therefore, I assume, this is a bug directly related to the security manager.

Without the security manager enabled, all requests are handled fine, even when stress testing.


Exception:

Exception in thread "anInnocuousThread" java.lang.SecurityException: setContextClassLoader
at sun.misc.InnocuousThread.setContextClassLoader(InnocuousThread.java:64)
at org.apache.tomcat.util.security.PrivilegedSetTccl.run(PrivilegedSetTccl.java:31)
at org.apache.tomcat.util.security.PrivilegedSetTccl.run(PrivilegedSetTccl.java:21)
at java.security.AccessController.doPrivileged(Native Method)
at org.apache.tomcat.util.threads.TaskThreadFactory.newThread(TaskThreadFactory.java:66)
at java.util.concurrent.ThreadPoolExecutor$Worker.<init>(ThreadPoolExecutor.java:610)
at java.util.concurrent.ThreadPoolExecutor.addWorker(ThreadPoolExecutor.java:924)
at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:1371)

at org.apache.tomcat.util.threads.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:167)
at org.apache.tomcat.util.threads.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:145)
at sun.nio.ch.AsynchronousChannelGroupImpl.executeOnPooledThread(AsynchronousChannelGroupImpl.java:188)
at sun.nio.ch.Invoker.invokeIndirectly(Invoker.java:212)
at sun.nio.ch.UnixAsynchronousSocketChannelImpl.finishRead(UnixAsynchronousSocketChannelImpl.java:432)
at sun.nio.ch.UnixAsynchronousSocketChannelImpl.finish(UnixAsynchronousSocketChannelImpl.java:191)
at sun.nio.ch.UnixAsynchronousSocketChannelImpl.onEvent(UnixAsynchronousSocketChannelImpl.java:213)
at sun.nio.ch.EPollPort$EventHandlerTask.run(EPollPort.java:293)
at java.lang.Thread.run(Thread.java:745)
at sun.misc.InnocuousThread.run(InnocuousThread.java:74)


Environment:

# uname -a
Linux 3.16.0-4-amd64 #1 SMP Debian 3.16.43-2+deb8u1 (2017-06-18) x86_64 GNU/Linux

# java -version
java version "1.7.0_131"
OpenJDK Runtime Environment (IcedTea 2.6.9) (7u131-2.6.9-2~deb8u1)
OpenJDK 64-Bit Server VM (build 24.131-b00, mixed mode)
Comment 1 Mark Thomas 2017-10-06 12:37:17 UTC
InnocuousThread is hard-coded to throw a SecurityException if you try and set the context class loader.

I can reproduce this with a clean 8.5.x build configured to use NIO2, a SecurityManager and JMeter running 100 threads POSTing data to one of the example servlets.

Looking at fix options now...
Comment 2 Remy Maucherat 2017-10-06 12:55:14 UTC
I had no idea about that weird behavior ... Catch the exception and ignore maybe, or get the thread name and avoid calling it for that "Innocuous" ? You moved the code there for performance reasons originally.
Comment 3 Mark Thomas 2017-10-06 13:37:38 UTC
The ultimate aim of the code is to make sure that any thread doesn't end up with the web application class loader as its context class loader. Rather than setting the class loader for the current thread that is then picked up by the new thread, I went for setting it on the new thread. That should meet the overall objective and avoid the issue with InnocuousThread.

Fixed in:
- trunk for 9.0.2 onwards
- 8.5.x for 8.5.24 onwards
- 8.0.x for 8.0.48 onwards