Return-Path: X-Original-To: apmail-tomcat-users-archive@www.apache.org Delivered-To: apmail-tomcat-users-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 256F492F1 for ; Fri, 20 Apr 2012 21:47:55 +0000 (UTC) Received: (qmail 82449 invoked by uid 500); 20 Apr 2012 21:47:51 -0000 Delivered-To: apmail-tomcat-users-archive@tomcat.apache.org Received: (qmail 82408 invoked by uid 500); 20 Apr 2012 21:47:51 -0000 Mailing-List: contact users-help@tomcat.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: "Tomcat Users List" Delivered-To: mailing list users@tomcat.apache.org Received: (qmail 82396 invoked by uid 99); 20 Apr 2012 21:47:51 -0000 Received: from nike.apache.org (HELO nike.apache.org) (192.87.106.230) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 20 Apr 2012 21:47:51 +0000 X-ASF-Spam-Status: No, hits=0.0 required=5.0 tests=MSGID_MULTIPLE_AT,RCVD_IN_DNSWL_NONE,SPF_PASS,UNPARSEABLE_RELAY X-Spam-Check-By: apache.org Received-SPF: pass (nike.apache.org: local policy) Received: from [194.25.134.20] (HELO mailout08.t-online.de) (194.25.134.20) by apache.org (qpsmtpd/0.29) with ESMTP; Fri, 20 Apr 2012 21:47:43 +0000 Received: from fwd22.aul.t-online.de (fwd22.aul.t-online.de ) by mailout08.t-online.de with smtp id 1SLLfn-0005Zz-2v; Fri, 20 Apr 2012 23:47:23 +0200 Received: from Preissa (SyTBtyZdZhHWXbP4WzBMoUMPON3iHbikeUk9QroO6qPL21UAjw4mQUWgggL77bDZ3f@[217.95.115.213]) by fwd22.t-online.de with esmtp id 1SLLfY-03MR4S0; Fri, 20 Apr 2012 23:47:08 +0200 From: =?utf-8?Q?Konstantin_Prei=C3=9Fer?= To: "'Tomcat Users List'" Subject: BufferOverflowException in Tomcat 7.0.x at AjpAprProcessor.output() Date: Fri, 20 Apr 2012 23:47:06 +0200 Message-ID: <000001cd1f3f$217c5710$64750530$@preisser@t-online.de> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-Mailer: Microsoft Office Outlook 12.0 Thread-Index: Ac0fPyFLZaA2Tb7sTr64ZM7pAX3rhQ== Content-Language: de X-ID: SyTBtyZdZhHWXbP4WzBMoUMPON3iHbikeUk9QroO6qPL21UAjw4mQUWgggL77bDZ3f X-TOI-MSGID: a0e781bf-1fea-49b8-bdab-76b27d786e22 Hi all, some time ago, I wrote about a BufferOverflowException which I got = sporadically on my Tomcat 7.0.21 [1], when using the AJP-APR-Connector. However, at that time I couldn't reproduce the exception. When I looked at this again today, I was able to create a client that = sends an AJP message and aborts the connection, resulting in the = BufferOverflowException in Tomcat. I was using Tomcat 7.0.27 with Tomcat = Native 1.1.23, on Oracle JDK 1.7.0_03 and Windows 7 32-bit. To reproduce, 1. On the Server side, create a web application containing a servlet = which will generate some random data: @WebServlet("/index.html") public class MyTestServlet extends HttpServlet { private static final long serialVersionUID =3D 1L; =20 protected void doGet(HttpServletRequest request, HttpServletResponse = response) throws ServletException, IOException { try { response.setContentType("text/plain"); response.setCharacterEncoding("utf-8"); =20 byte[] bytesToWrite =3D {48, 49, 50, 51, 52, 53, 54, 55, 56, = 57}; =20 // Try to write 1,000,000 bytes to the client. try (OutputStream out =3D response.getOutputStream()) { for (int i =3D 0; i < 100000; i++) { out.write(bytesToWrite); } } =20 } catch (IOException ex) { // Ignore } } } Deploy the application as ROOT, so that the servlet will be reachable at = "/". Configure Tomcat to have an AJP-APR connector listening on port 8009. 2. On the client side, create a program like this: public class AjpTester { public static void main(String[] args) throws IOException { byte[] ajpPacketBytes =3D { // JK_AJP13_FORWARD_REQUEST for "/" 0x12, 0x34, 0x00, 0x54, 0x02, 0x02, 0x00, 0x08, 0x48, 0x54, 0x54, 0x50, 0x2f, 0x31, 0x2e, 0x31, 0x00, 0x00, 0x01, 0x2f, 0x00, 0x00, 0x07, 0x31, 0x2e, 0x32, 0x2e, 0x33, 0x2e, 0x34, 0x00, 0x00, 0x07, 0x31, 0x2e, 0x32, 0x2e, 0x33, 0x2e, 0x34, 0x00, 0x00, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x00, 0x00, 0x50, 0x00, 0x00, 0x02, (byte)0xa0, 0x06, 0x00, 0x0a, 0x4b, 0x65, 0x65, 0x70, 0x2d, 0x41, 0x6c, 0x69, 0x76, 0x65, 0x00, (byte)0xa0, 0x0b, 0x00, 0x09, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x68, 0x6f, 0x73, 0x74, 0x00, (byte)0xff }; Socket s =3D new Socket("localhost", 8009); // connect to AJP = port OutputStream sout =3D s.getOutputStream(); InputStream sin =3D s.getInputStream(); sout.write(ajpPacketBytes); // request Url "/" // Read between 10,000 and 11,023 bytes, then exit the JVM byte[] buf =3D new byte[1024]; int read; int bytesRead =3D 0; while ((read =3D sin.read(buf)) > 0) { bytesRead +=3D read; if (bytesRead >=3D 10000) { System.exit(1); } } } } The client will send an JK_AJP13_FORWARD_REQUEST message which requests = URL "/" and sends "Connection: keep-alive" and "Host: localhost" = headers. 3. Tomcat will display this exception: Apr 20, 2012 10:57:08 PM org.apache.coyote.ajp.AjpAprProcessor process Schwerwiegend: Error processing request java.nio.BufferOverflowException at java.nio.DirectByteBuffer.put(DirectByteBuffer.java:357) at = org.apache.coyote.ajp.AjpAprProcessor.output(AjpAprProcessor.java:285) at = org.apache.coyote.ajp.AbstractAjpProcessor$SocketOutputBuffer.doWrite(Abs= tractAjpProcessor.java:1119) at org.apache.coyote.Response.doWrite(Response.java:504) at = org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.ja= va:383) at org.apache.tomcat.util.buf.ByteChunk.flushBuffer(ByteChunk.java:462) at = org.apache.catalina.connector.OutputBuffer.doFlush(OutputBuffer.java:334)= at = org.apache.catalina.connector.OutputBuffer.close(OutputBuffer.java:283) at = org.apache.catalina.connector.Response.finishResponse(Response.java:511) at = org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:43= 4) at = org.apache.coyote.ajp.AjpAprProcessor.process(AjpAprProcessor.java:197) at = org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(Abst= ractProtocol.java:565) at = org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.ja= va:1812) at = java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java= :1110) at = java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.jav= a:603) at java.lang.Thread.run(Thread.java:722) I guess the exception itself is harmless, but it may fill up log files, = if clients disconnect frequently while receiving data. Note that before that exception occurs, a regular "ClientAbortException: = java.io.IOException: Failed to send AJP message" is thrown by = org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.ja= va:388). The exception occurs neither with AJP-BIO nor with AJP-NIO. Regards, Konstantin Prei=C3=9Fer [1] http://markmail.org/message/zogi3tfbz2kyw3jg --------------------------------------------------------------------- To unsubscribe, e-mail: users-unsubscribe@tomcat.apache.org For additional commands, e-mail: users-help@tomcat.apache.org