Bug 53366 - Running with SecurityManager: protected/index.jsp returns blank page when it is the first page accessed
Summary: Running with SecurityManager: protected/index.jsp returns blank page when it ...
Status: RESOLVED FIXED
Alias: None
Product: Tomcat 7
Classification: Unclassified
Component: Catalina (show other bugs)
Version: 7.0.27
Hardware: PC Windows XP
: P2 minor (vote)
Target Milestone: ---
Assignee: Tomcat Developers Mailing List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2012-06-06 00:51 UTC by Konstantin Kolinko
Modified: 2012-06-06 18:32 UTC (History)
0 users



Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Konstantin Kolinko 2012-06-06 00:51:35 UTC
eproducible in 7.0.27 and in current 7.0.x.

To reproduce:
1. Start "catalina.bat start -security"
2. Go to
[1] http://localhost:8080/examples/jsp/security/protected/index.jsp

3. Expected result: Display login form.
Actual result:
 Blank page. Access log shows:
127.0.0.1 - - [06/Jun/2012:04:35:23 +0400] "GET /examples/jsp/security/protected/index.jsp HTTP/1.1" 200 -

That is, response code is 200, count of bytes is '-'.


If I stay on [1] and keep refreshing it, the problem persists.

But if I visit [2], then [1] starts to work. I suspect that some class needs to be preloaded.

[2] http://localhost:8080/examples/
Comment 1 Konstantin Kolinko 2012-06-06 02:04:38 UTC
I turned on fine logging for coyote, catalina and tomcat.

There are no stacktraces being printed.

The first notable difference between failed run with -security and
successful run without -security is that in the failed run I see

FINE: loadClass(javax.servlet.jsp.SkipPageException, false)

while on successful run I see no such class being loaded.


The second is that on successful run I see debug messages from
 org.apache.tomcat.util.buf.UEncoder
while on failed one I do not see them.

Looking into generated Java code, login_jsp.java,  I see the following block:

[[[
    try {
      response.setContentType("text/html");
      pageContext = _jspxFactory.getPageContext(this, request, response,
      			null, true, 8192, true);
      _jspx_page_context = pageContext;
      application = pageContext.getServletContext();
      config = pageContext.getServletConfig();
      session = pageContext.getSession();
      out = pageContext.getOut();
      _jspx_out = out;

      out.write("\r\n");
      out.write("<html>\r\n");
      out.write("<head>\r\n");
      out.write("<title>Login Page for Examples</title>\r\n");
      out.write("<body bgcolor=\"white\">\r\n");
      out.write("<form method=\"POST\" action='");
      out.print( response.encodeURL("j_security_check") );
      (...)
    } catch (java.lang.Throwable t) {
      if (!(t instanceof javax.servlet.jsp.SkipPageException)){
        out = _jspx_out;
        if (out != null && out.getBufferSize() != 0)
          try { out.clearBuffer(); } catch (java.io.IOException e) {}
        if (_jspx_page_context != null) _jspx_page_context.handlePageException(t);
      }
    } finally {
      _jspxFactory.releasePageContext(_jspx_page_context);
    }
]]]


So, two conclusions:
1. The failure occurs above "response.encodeURL("j_security_check")" call.
2. I suspect that _jspx_page_context is null.  In that case the Throwable in the catch block is silently swallowed.

This effect reminds me bug 48097,
https://issues.apache.org/bugzilla/show_bug.cgi?id=48097#c7

I think if (_jspx_page_context is null) we could write something to debug logging, as these issues keep occurring and seeing a stacktrace should help.
Comment 2 Konstantin Kolinko 2012-06-06 13:44:56 UTC
I improved logging in r1346885

Stacktrace:
[[[
06-Jun-2012 17:28:01.640 SEVERE [http-bio-8080-exec-1] org.apache.catalina.core.ApplicationContext.log jsp: access denied (java.lang.RuntimePermission accessClassInPackage.org.apache.tomcat.util.http.parser)
 java.security.AccessControlException: access denied (java.lang.RuntimePermission accessClassInPackage.org.apache.tomcat.util.http.parser)
	at java.security.AccessControlContext.checkPermission(AccessControlContext.java:374)
	at java.security.AccessController.checkPermission(AccessController.java:546)
	at java.lang.SecurityManager.checkPermission(SecurityManager.java:532)
	at java.lang.SecurityManager.checkPackageAccess(SecurityManager.java:1512)
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:298)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:295)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
	at org.apache.catalina.connector.Response.setContentType(Response.java:708)
	at org.apache.jsp.jsp.security.protected_.login_jsp._jspService(login_jsp.java:52)
	at org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:70)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
	at org.apache.jasper.servlet.JspServletWrapper.service(JspServletWrapper.java:432)
	at org.apache.jasper.servlet.JspServlet.serviceJspFile(JspServlet.java:390)
	at org.apache.jasper.servlet.JspServlet.service(JspServlet.java:334)
	at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at org.apache.catalina.security.SecurityUtil$1.run(SecurityUtil.java:274)
	at org.apache.catalina.security.SecurityUtil$1.run(SecurityUtil.java:271)
	at java.security.AccessController.doPrivileged(Native Method)
	at javax.security.auth.Subject.doAsPrivileged(Subject.java:517)
	at org.apache.catalina.security.SecurityUtil.execute(SecurityUtil.java:306)
	at org.apache.catalina.security.SecurityUtil.doAsPrivilege(SecurityUtil.java:166)
	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:299)
	at org.apache.catalina.core.ApplicationFilterChain.access$000(ApplicationFilterChain.java:57)
	at org.apache.catalina.core.ApplicationFilterChain$1.run(ApplicationFilterChain.java:193)
	at org.apache.catalina.core.ApplicationFilterChain$1.run(ApplicationFilterChain.java:189)
	at java.security.AccessController.doPrivileged(Native Method)
	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:188)
	at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:670)
	at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:457)
	at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:382)
	at org.apache.catalina.core.ApplicationDispatcher.access$000(ApplicationDispatcher.java:67)
	at org.apache.catalina.core.ApplicationDispatcher$PrivilegedForward.run(ApplicationDispatcher.java:102)
	at org.apache.catalina.core.ApplicationDispatcher$PrivilegedForward.run(ApplicationDispatcher.java:89)
	at java.security.AccessController.doPrivileged(Native Method)
	at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:301)
	at org.apache.catalina.authenticator.FormAuthenticator.forwardToLoginPage(FormAuthenticator.java:390)
	at org.apache.catalina.authenticator.FormAuthenticator.authenticate(FormAuthenticator.java:256)
	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:546)
	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:146)
	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:74)
	at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:911)
	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:90)
	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
	at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:995)
	at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:573)
	at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:145)
	at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:311)
	at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
	at java.lang.Thread.run(Thread.java:662)
]]]

If I add the following line to "grant {};" section of catalina.policy,
the problem disappears:

    permission java.lang.RuntimePermission "accessClassInPackage.org.apache.tomcat.util.http.parser";

If, alternatively, I preload those classes by adding the following attribute to JreMemoryLeakPreventionListener in server.xml,
the problem disappears as well:

classesToInitialize="
org.apache.tomcat.util.http.parser.AstAttribute,
org.apache.tomcat.util.http.parser.AstMediaType,
org.apache.tomcat.util.http.parser.AstParameter,
org.apache.tomcat.util.http.parser.AstSubType,
org.apache.tomcat.util.http.parser.AstType,
org.apache.tomcat.util.http.parser.AstValue,
org.apache.tomcat.util.http.parser.HttpParser,
org.apache.tomcat.util.http.parser.HttpParserConstants,
org.apache.tomcat.util.http.parser.HttpParserTokenManager,
org.apache.tomcat.util.http.parser.HttpParserTreeConstants,
org.apache.tomcat.util.http.parser.JJTHttpParserState,
org.apache.tomcat.util.http.parser.Node,
org.apache.tomcat.util.http.parser.ParseException,
org.apache.tomcat.util.http.parser.SimpleCharStream,
org.apache.tomcat.util.http.parser.SimpleNode,
org.apache.tomcat.util.http.parser.Token,
org.apache.tomcat.util.http.parser.TokenMgrError
"
Comment 3 Mark Thomas 2012-06-06 18:32:34 UTC
Fixed in trunk and 7.0.x and will be included in 7.0.28 onwards.