Uploaded image for project: 'Undertow'
  1. Undertow
  2. UNDERTOW-1558

security-manager and reflection permissions in DirectByteBufferDeallocator/undertow

    XMLWordPrintable

Details

    • Bug
    • Resolution: Done
    • Major
    • 2.0.22.Final
    • 2.0.21.Final
    • Core
    • None
    • 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".

    Description

      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)
              ...
      

      Attachments

        Issue Links

          Activity

            People

              rhn-support-tmiyargi Teresa Miyar Gil (Inactive)
              rhn-support-tmiyargi Teresa Miyar Gil (Inactive)
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: