Uploaded image for project: 'JBoss Enterprise Application Platform'
  1. JBoss Enterprise Application Platform
  2. JBEAP-17052

[GSS](7.2.z) UNDERTOW-1558 - security-manager and reflection permissions in DirectByteBufferDeallocator/undertow

XMLWordPrintable

    • +
    • Hide

      I have reproduced the issue with a modified version of the helloworld-ssl that contains the following doPost method in the HelloWorldServlet:

        public void doPost(HttpServletRequest request, HttpServletResponse response)
          throws IOException
        {
          int bytesRead = 0;
          
          BufferedReader br = new BufferedReader(new InputStreamReader(request.getInputStream()));
          int b = br.read();
          while (b != -1)
          {
            bytesRead++;
            b = br.read();
          }
          System.out.println("Bytes read: " + bytesRead);
        }
      

      Configure the buffers to be very restricted:

      /subsystem=undertow/byte-buffer-pool=pool:add(max-pool-size=2, buffer-size=256)
      /subsystem=undertow/server=default-server/https-listener=https:write-attribute(name=buffer-pool, value=newpool)
      

      Then just launch at least two threads with the following curl:

      while [ true ]
      do
      curl -s -o /dev/null -w "%{http_code}\n" -k -d "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789" https://localhost:8443//helloworld-ssl/HelloWorld
      done
      

      The two threads triggers the free of a buffer and the exception is thrown. Look the server.log for the "Permission check failed".

      Show
      I have reproduced the issue with a modified version of the helloworld-ssl that contains the following doPost method in the HelloWorldServlet: public void doPost(HttpServletRequest request, HttpServletResponse response) throws IOException { int bytesRead = 0; BufferedReader br = new BufferedReader( new InputStreamReader(request.getInputStream())); int b = br.read(); while (b != -1) { bytesRead++; b = br.read(); } System .out.println( "Bytes read: " + bytesRead); } Configure the buffers to be very restricted: /subsystem=undertow/byte-buffer-pool=pool:add(max-pool-size=2, buffer-size=256) /subsystem=undertow/server=default-server/https-listener=https:write-attribute(name=buffer-pool, value=newpool) Then just launch at least two threads with the following curl: while [ true ] do curl -s -o /dev/null -w "%{http_code}\n" -k -d "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789" https://localhost:8443//helloworld-ssl/HelloWorld done The two threads triggers the free of a buffer and the exception is thrown. Look the server.log for the "Permission check failed".

      When using an application that uses SSL, the class DirectByteBufferDeallocator is wrongly initialized if the security manager is enabled. That class is only used when a buffer should be freed so it's complicated to trigger the error. The exception generated is like the following:

      2019-06-13 09:21:47,862 ERROR [io.undertow] (default task-1) UT005091: Failed to initialize DirectByteBufferDeallocator: java.security.AccessControlException: WFSM000001: Permission check failed (permission "("java.lang.reflect.ReflectPermission" "suppressAccessChecks")" in code source "(vfs:/content/helloworld-ssl.war/WEB-INF/classes <no signer certificates>)" of "ModuleClassLoader for Module "deployment.helloworld-ssl.war" from Service Module Loader")
              at org.wildfly.security.manager.WildFlySecurityManager.checkPermission(WildFlySecurityManager.java:295)
              at org.wildfly.security.manager.WildFlySecurityManager.checkPermission(WildFlySecurityManager.java:192)
              at java.lang.reflect.AccessibleObject.setAccessible(AccessibleObject.java:128)
              at io.undertow.server.DirectByteBufferDeallocator.<clinit>(DirectByteBufferDeallocator.java:37)
              at io.undertow.server.DefaultByteBufferPool.queueIfUnderMax(DefaultByteBufferPool.java:209)
              at io.undertow.server.DefaultByteBufferPool.freeInternal(DefaultByteBufferPool.java:201)
              at io.undertow.server.DefaultByteBufferPool.access$200(DefaultByteBufferPool.java:40)
              at io.undertow.server.DefaultByteBufferPool$DefaultPooledBuffer.close(DefaultByteBufferPool.java:271)
              at io.undertow.servlet.spec.ServletInputStreamImpl.read(ServletInputStreamImpl.java:179)
              at sun.nio.cs.StreamDecoder.readBytes(StreamDecoder.java:284)
              at sun.nio.cs.StreamDecoder.implRead(StreamDecoder.java:326)
              at sun.nio.cs.StreamDecoder.read(StreamDecoder.java:178)
              at java.io.InputStreamReader.read(InputStreamReader.java:184)
              at java.io.BufferedReader.fill(BufferedReader.java:161)
              at java.io.BufferedReader.read(BufferedReader.java:182)
              at org.jboss.as.quickstarts.helloworld.HelloWorldServlet.doPost(HelloWorldServlet.java:68)
              at javax.servlet.http.HttpServlet.service(HttpServlet.java:706)
              at javax.servlet.http.HttpServlet.service(HttpServlet.java:791)
              ...
      

            rhn-support-tmiyargi Teresa Miyar Gil (Inactive)
            rhn-support-rmartinc Ricardo Martin Camarero
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated:
              Resolved: