Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
Bug 327482 - OSGI app binaries do not inherit Java 2 security
Summary: OSGI app binaries do not inherit Java 2 security
Status: RESOLVED FIXED
Alias: None
Product: Equinox
Classification: Eclipse Project
Component: Server-Side (show other bugs)
Version: unspecified   Edit
Hardware: PC Windows XP
: P3 major (vote)
Target Milestone: 3.7 M4   Edit
Assignee: equinox.server-side-inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks: 329204 329212
  Show dependency tree
 
Reported: 2010-10-11 15:22 EDT by jcr2548 CLA
Modified: 2010-11-01 13:59 EDT (History)
3 users (show)

See Also:


Attachments
proposed patch (2.54 KB, patch)
2010-10-11 21:13 EDT, Simon Kaegi CLA
no flags Details | Diff
ffdc log of the AccessControlException (23.50 KB, text/plain)
2010-10-12 09:59 EDT, jcr2548 CLA
no flags Details
proposed patch v2 (5.14 KB, patch)
2010-10-26 14:59 EDT, Simon Kaegi CLA
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description jcr2548 CLA 2010-10-11 15:22:04 EDT
AccessControlException seen when an OSGI application is run in WebSphere when Java 2 security is enabled.

Steps to Recreate:
Install an OSGI web application in WebSphere and enable Java 2 security.
When I attempt to load the application, I get exceptions in the log:

Permission:
      setContextClassLoader : Access denied (java.lang.RuntimePermission setContextClassLoader)

Code:
     org.apache.jsp.index_jsp  in  {file:/G:/wasX/profiles/Dmgr02/temp/HumeCellManager41/dmgr/isclite/iehs.war/proxytemp/hc_30600740/}

Stack Trace:
java.security.AccessControlException: Access denied (java.lang.RuntimePermission setContextClassLoader)
	at java.security.AccessController.checkPermission(AccessController.java:108)
	at java.lang.SecurityManager.checkPermission(SecurityManager.java:533)
	at com.ibm.ws.security.core.SecurityManager.checkPermission(SecurityManager.java:212)
	at java.lang.Thread.setContextClassLoader(Thread.java:754)
	at com.ibm.ws.util.ThreadPool$Worker.setContextClassLoader(ThreadPool.java:1773)
	at org.eclipse.equinox.servletbridge.BridgeServlet.service(BridgeServlet.java:120)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:668)
	at com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1138)
	at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:708)
	at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:435)

The problem is that the was.policy file which grants AllPermission to the ear does not get applied to the OSGI war binaries which have been extracted to the temp directory.
A known workaround is to edit the server.policy file to grant AllPermission for this temp path as the codeBase. This workaround should not be needed if the permissions are inherited correctly from the ear's .policy file.

We think the issue is the org.eclipse.equinox.servletbridge.BridgeServlet class uses the class loader org.eclipse.equinox.servletbridge.CloseableURLClassLoader to load the framework (the jars that got extracted to the temp directory).  The CloseableClassLoader extends URLClassLoader.  By default the URLClassLoader uses the built in policy.  I think WAS sets up a built-in security policy that only understands how to grant permissions to the server's codebase and to class loaders it controls.  It knows nothing about CloseableClassLoader.  I think CloseableClassLoader should override the method java.net.URLClassLoader.getPermissions(CodeSource) in order to grant all permissions to the framework jar (codebase) that it extracted.
Comment 1 Simon Kaegi CLA 2010-10-11 21:01:30 EDT
I think we need to see more of the stack as judging by the code portion of the exception the error is occuring because a compiled JSP class is on the stack and I don't see that in the shallow stack shown.

Although CloseableURLClassLoader does not implement getPermissions the actual CL used to load the framework extends and implements getPermissions. If I was to guess I bet the problem is the JSP Classloader and it needs to implement getPermissions and either grant AllPermissions or defer to ConditionalPermissionsAdmin.
Comment 2 Simon Kaegi CLA 2010-10-11 21:13:22 EDT
Created attachment 180627 [details]
proposed patch
Comment 3 Simon Kaegi CLA 2010-10-11 21:54:42 EDT
We likely will have some additional work to override the getPermissions done inside Jasper. JSPRuntimeContext provides the permission collection that we would have to override.
Comment 4 jcr2548 CLA 2010-10-12 09:58:21 EDT
Here is the complete stack trace for the first exception.
I will attach the related ffdc also.

[10/7/10 13:25:56:501 EDT] 00000015 FfdcProvider  W com.ibm.ws.ffdc.impl.FfdcProvider logIncident FFDC1003I: FFDC Incident emitted on G:\was8_ff1039.14\profiles\Dmgr02\logs\ffdc\dmgr_1ef9e52_10.10.07_13.25.56.4234835237337533450997.txt com.ibm.ws.security.core.SecurityManager 180
[10/7/10 13:25:56:501 EDT] 00000015 SecurityManag W   SECJ0314W: Current Java 2 Security policy reported a potential violation of Java 2 Security Permission. Refer to the InfoCenter for further information.

Permission:

      setContextClassLoader : Access denied (java.lang.RuntimePermission setContextClassLoader)


Code:

     org.apache.jsp.index_jsp  in  {file:/G:/was8_ff1039.14/profiles/Dmgr02/temp/HumeCellManager41/dmgr/isclite/iehs.war/proxytemp/hc_31397975/}



Stack Trace:

java.security.AccessControlException: Access denied (java.lang.RuntimePermission setContextClassLoader)
	at java.security.AccessController.checkPermission(AccessController.java:108)
	at java.lang.SecurityManager.checkPermission(SecurityManager.java:533)
	at com.ibm.ws.security.core.SecurityManager.checkPermission(SecurityManager.java:212)
	at java.lang.Thread.setContextClassLoader(Thread.java:754)
	at com.ibm.ws.util.ThreadPool$Worker.setContextClassLoader(ThreadPool.java:1773)
	at org.eclipse.equinox.servletbridge.BridgeServlet.service(BridgeServlet.java:120)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:668)
	at com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1138)
	at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:708)
	at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:435)
	at com.ibm.ws.webcontainer.servlet.ServletWrapperImpl.handleRequest(ServletWrapperImpl.java:178)
	at com.ibm.ws.webcontainer.filter.WebAppFilterManager.invokeFilters(WebAppFilterManager.java:1012)
	at com.ibm.ws.webcontainer.webapp.WebAppRequestDispatcher.dispatch(WebAppRequestDispatcher.java:1370)
	at com.ibm.ws.webcontainer.webapp.WebAppRequestDispatcher.forward(WebAppRequestDispatcher.java:179)
	at org.eclipse.equinox.http.servlet.internal.RequestDispatcherAdaptor.forward(RequestDispatcherAdaptor.java:30)
	at org.apache.jasper.runtime.PageContextImpl.doForward(PageContextImpl.java:703)
	at org.apache.jasper.runtime.PageContextImpl.forward(PageContextImpl.java:670)
	at org.apache.jasper.runtime.PageContextImpl.doHandlePageException(PageContextImpl.java:818)
	at org.apache.jasper.runtime.PageContextImpl.handlePageException(PageContextImpl.java:791)
	at org.apache.jsp.index_jsp._jspService(index_jsp.java:87)
	at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:97)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:668)
	at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:332)
	at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:314)
	at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:264)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:668)
	at org.eclipse.equinox.jsp.jasper.JspServlet.service(JspServlet.java:112)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:668)
	at org.eclipse.equinox.http.registry.internal.ServletManager$ServletWrapper.service(ServletManager.java:180)
	at org.eclipse.equinox.http.servlet.internal.ServletRegistration.handleRequest(ServletRegistration.java:90)
	at org.eclipse.equinox.http.servlet.internal.ProxyServlet.processAlias(ProxyServlet.java:111)
	at org.eclipse.equinox.http.servlet.internal.ProxyServlet.service(ProxyServlet.java:75)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:668)
	at org.eclipse.equinox.servletbridge.BridgeServlet.service(BridgeServlet.java:121)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:668)
	at com.ibm.ws.webcontainer.servlet.ServletWrapper.service(ServletWrapper.java:1138)
	at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:708)
	at com.ibm.ws.webcontainer.servlet.ServletWrapper.handleRequest(ServletWrapper.java:435)
	at com.ibm.ws.webcontainer.servlet.ServletWrapperImpl.handleRequest(ServletWrapperImpl.java:178)
	at com.ibm.ws.webcontainer.filter.WebAppFilterManager.invokeFilters(WebAppFilterManager.java:1012)
	at com.ibm.ws.webcontainer.webapp.WebApp.handleRequest(WebApp.java:3598)
	at com.ibm.ws.webcontainer.webapp.WebGroup.handleRequest(WebGroup.java:303)
	at com.ibm.ws.webcontainer.WebContainer.handleRequest(WebContainer.java:950)
	at com.ibm.ws.webcontainer.WSWebContainer.handleRequest(WSWebContainer.java:1625)
	at com.ibm.ws.webcontainer.channel.WCChannelLink.ready(WCChannelLink.java:197)
	at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.handleDiscrimination(HttpInboundLink.java:445)
	at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.handleNewRequest(HttpInboundLink.java:504)
	at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.processRequest(HttpInboundLink.java:301)
	at com.ibm.ws.http.channel.inbound.impl.HttpInboundLink.ready(HttpInboundLink.java:275)
	at com.ibm.ws.ssl.channel.impl.SSLConnectionLink.determineNextChannel(SSLConnectionLink.java:1016)
	at com.ibm.ws.ssl.channel.impl.SSLConnectionLink$MyReadCompletedCallback.complete(SSLConnectionLink.java:639)
	at com.ibm.ws.ssl.channel.impl.SSLReadServiceContext$SSLReadCompletedCallback.complete(SSLReadServiceContext.java:1784)
	at com.ibm.ws.tcp.channel.impl.AioReadCompletionListener.futureCompleted(AioReadCompletionListener.java:165)
	at com.ibm.io.async.AbstractAsyncFuture.invokeCallback(AbstractAsyncFuture.java:217)
	at com.ibm.io.async.AsyncChannelFuture.fireCompletionActions(AsyncChannelFuture.java:161)
	at com.ibm.io.async.AsyncFuture.completed(AsyncFuture.java:138)
	at com.ibm.io.async.ResultHandler.complete(ResultHandler.java:204)
	at com.ibm.io.async.ResultHandler.runEventProcessingLoop(ResultHandler.java:775)
	at com.ibm.io.async.ResultHandler$2.run(ResultHandler.java:905)
	at com.ibm.ws.util.ThreadPool$Worker.run(ThreadPool.java:1618)
Comment 5 jcr2548 CLA 2010-10-12 09:59:14 EDT
Created attachment 180669 [details]
ffdc log of the AccessControlException
Comment 6 jcr2548 CLA 2010-10-13 12:55:17 EDT
Is the posted proposed patch ready to be built and tested? If so, can you provde a patched build or jar for me to try?

Is there an ETA for the fix?
Comment 7 Thomas Watson CLA 2010-10-13 13:28:41 EDT
See comment 3.  I don't think the proposed patch would be a complete fix.
Comment 8 Simon Kaegi CLA 2010-10-13 14:32:27 EDT
(In reply to comment #7)
> See comment 3.  I don't think the proposed patch would be a complete fix.

Indeed.
To fix up the permissions in the JSP Engine I can think of two not particularly desirable alternatives. Either:
1) use reflection to alter the PermissionsCollection on the JSPRuntimeContext
or
2) Temporarily lock and set (and later reset) the Policy object while we are initializing the JSPServlet.

(1) is going to be fairly code dependent but is likely less intrusive than messing with the Policy object so I'm thinking that it's likely the way to go. Any thoughts Tom?

As far as timing goes I cannot look at this immediately but we can likely still slot this in for M4.
Comment 9 Thomas Watson CLA 2010-10-13 15:44:10 EDT
(In reply to comment #8)
> 
> (1) is going to be fairly code dependent but is likely less intrusive than
> messing with the Policy object so I'm thinking that it's likely the way to go.
> Any thoughts Tom?
> 
I agree using a policy sounds pretty messy.  Lesser of two evils is using the reflective approach.
Comment 10 Simon Kaegi CLA 2010-10-26 14:59:23 EDT
Created attachment 181758 [details]
proposed patch v2

Here's what we hope is a complete fix.

This patch overrides the permissions for the JasperRuntimeContext instance to match those of the bundle creating the JSPServlet. This particular codepath is only followed if a SecurityManager is set.

I've tried this patch out with simple tests on my end and it appears to behave as I expect however I have not committed this patch to HEAD. At this point I think we need some validation ensure the problem is handled in your environment.
Comment 11 jcr2548 CLA 2010-10-26 16:09:49 EDT
I would be happy to try it in my environment. Are you able to provide a compiled class or jar for me to patch my installation?
Comment 12 Simon Kaegi CLA 2010-10-30 16:10:07 EDT
We validated that this fix works correctly.
Comment 13 Simon Kaegi CLA 2010-11-01 13:59:03 EDT
As part of reviewing bug 32904 Tom pointed out an unnecessary code path for which the changes are now also removed in HEAD.