[pkg-java] r16000 - in trunk/jetty/debian: . patches
Niels Thykier
nthykier at alioth.debian.org
Wed Apr 25 10:01:33 UTC 2012
Author: nthykier
Date: 2012-04-25 10:01:33 +0000 (Wed, 25 Apr 2012)
New Revision: 16000
Added:
trunk/jetty/debian/patches/CVE-2011-4461.patch
Modified:
trunk/jetty/debian/changelog
trunk/jetty/debian/patches/series
Log:
Apply fix for CVE-2011-4461
Modified: trunk/jetty/debian/changelog
===================================================================
--- trunk/jetty/debian/changelog 2012-04-25 09:57:30 UTC (rev 15999)
+++ trunk/jetty/debian/changelog 2012-04-25 10:01:33 UTC (rev 16000)
@@ -7,11 +7,13 @@
* Updated d/copyright to DEP-5 format 1.0.
* Exit 0 in jetty's init script if jetty is already running.
Thanks to Toby for the report and patch. (Closes: #626382)
- * Fix mispelled "character-class" in grep invocation. Thanks
+ * Fix misspelled "character-class" in grep invocation. Thanks
to Isaac for the report and correction. (Closes: #637961)
* Allow java.library.path to be set in /etc/default/jetty.
Thanks to "biddster" for the report and the patches.
(Closes: #600175, LP: #656374)
+ * Apply patch from Fedora to fix hash collision related DOS.
+ - CVE-2011-4461
-- Niels Thykier <niels at thykier.net> Wed, 25 Apr 2012 11:06:04 +0200
Added: trunk/jetty/debian/patches/CVE-2011-4461.patch
===================================================================
--- trunk/jetty/debian/patches/CVE-2011-4461.patch (rev 0)
+++ trunk/jetty/debian/patches/CVE-2011-4461.patch 2012-04-25 10:01:33 UTC (rev 16000)
@@ -0,0 +1,376 @@
+Description: Fix for Hash collision, see CVE-2011-4461
+Origin: https://bugzilla.redhat.com/attachment.cgi?id=556318&action=diff
+
+--- a/modules/jetty/src/main/java/org/mortbay/jetty/handler/ContextHandler.java 2012-01-16 13:35:18.000000000 -0500
++++ b/modules/jetty/src/main/java/org/mortbay/jetty/handler/ContextHandler.java 2012-01-16 14:31:48.000000000 -0500
+@@ -118,6 +118,7 @@ public class ContextHandler extends Hand
+ private Logger _logger;
+ private boolean _shutdown;
+ private boolean _allowNullPathInfo;
++ private int _maxFormKeys = Integer.getInteger("org.eclipse.jetty.server.Request.maxFormKeys",1000).intValue();
+ private int _maxFormContentSize=Integer.getInteger("org.mortbay.jetty.Request.maxFormContentSize",200000).intValue();
+ private boolean _compactPath=false;
+
+@@ -1058,11 +1059,30 @@ public class ContextHandler extends Hand
+ }
+
+ /* ------------------------------------------------------------ */
++ /**
++ * Set the maximum size of a form post, to protect against DOS attacks from large forms.
++ * @param maxSize
++ */
+ public void setMaxFormContentSize(int maxSize)
+ {
+ _maxFormContentSize=maxSize;
+ }
+
++ /* ------------------------------------------------------------ */
++ public int getMaxFormKeys()
++ {
++ return _maxFormKeys;
++ }
++
++ /* ------------------------------------------------------------ */
++ /**
++ * Set the maximum number of form Keys to protect against DOS attack from crafted hash keys.
++ * @param max
++ */
++ public void setMaxFormKeys(int max)
++ {
++ _maxFormKeys = max;
++ }
+
+ /* ------------------------------------------------------------ */
+ /**
+--- a/modules/jetty/src/main/java/org/mortbay/jetty/Request.java 2012-01-16 13:24:22.000000000 -0500
++++ b/modules/jetty/src/main/java/org/mortbay/jetty/Request.java 2012-01-16 13:32:38.000000000 -0500
+@@ -98,6 +98,13 @@ import org.mortbay.util.ajax.Continuatio
+ * to avoid reparsing headers and cookies that are likely to be the same for
+ * requests from the same connection.
+ *
++ * <p>
++ * The form content that a request can process is limited to protect from Denial of Service
++ * attacks. The size in bytes is limited by {@link ContextHandler#getMaxFormContentSize()} or if there is no
++ * context then the "org.eclipse.jetty.server.Request.maxFormContentSize" {@link Server} attribute.
++ * The number of parameters keys is limited by {@link ContextHandler#getMaxFormKeys()} or if there is no
++ * context then the "org.eclipse.jetty.server.Request.maxFormKeys" {@link Server} attribute.
++ *
+ * @author gregw
+ *
+ */
+@@ -1546,16 +1553,23 @@ public class Request implements HttpServ
+ try
+ {
+ int maxFormContentSize=-1;
+-
++ int maxFormKeys=-1;
++
++
++
+ if (_context!=null)
++ {
+ maxFormContentSize=_context.getContextHandler().getMaxFormContentSize();
++ maxFormKeys=_context.getContextHandler().getMaxFormKeys();
++ }
+ else
+ {
+- Integer size = (Integer)_connection.getConnector().getServer().getAttribute("org.mortbay.jetty.Request.maxFormContentSize");
+- if (size!=null)
+- maxFormContentSize =size.intValue();
++ Number size = (Number)_connection.getConnector().getServer().getAttribute("org.eclipse.jetty.server.Request.maxFormContentSize");
++ maxFormContentSize=size==null?200000:size.intValue();
++ Number keys = (Number)_connection.getConnector().getServer().getAttribute("org.eclipse.jetty.server.Request.maxFormKeys");
++ maxFormKeys =keys==null?1000:keys.intValue();
+ }
+-
++
+ if (content_length>maxFormContentSize && maxFormContentSize > 0)
+ {
+ throw new IllegalStateException("Form too large"+content_length+">"+maxFormContentSize);
+@@ -1563,7 +1577,7 @@ public class Request implements HttpServ
+ InputStream in = getInputStream();
+
+ // Add form params to query params
+- UrlEncoded.decodeTo(in, _baseParameters, encoding,content_length<0?maxFormContentSize:-1);
++ UrlEncoded.decodeTo(in, _baseParameters, encoding,content_length<0?maxFormContentSize:-1,maxFormKeys);
+ }
+ catch (IOException e)
+ {
+--- a/modules/jetty/src/test/java/org/mortbay/jetty/RequestTest.java 2012-01-16 14:38:35.000000000 -0500
++++ b/modules/jetty/src/test/java/org/mortbay/jetty/RequestTest.java 2012-01-16 14:45:16.000000000 -0500
+@@ -15,10 +15,13 @@
+
+ package org.mortbay.jetty;
+
+-
++import java.io.BufferedReader;
++import java.io.File;
++import java.io.FileReader;
+ import java.io.IOException;
+ import java.io.Reader;
+ import java.util.ArrayList;
++import java.util.HashMap;
+
+ import javax.servlet.ServletException;
+ import javax.servlet.http.Cookie;
+@@ -28,10 +31,14 @@ import javax.servlet.http.HttpServletRes
+ import junit.framework.TestCase;
+
+ import org.mortbay.jetty.Request;
++import org.mortbay.jetty.MimeTypes;
+ import org.mortbay.jetty.handler.AbstractHandler;
+ import org.mortbay.jetty.handler.HandlerCollection;
+ import org.mortbay.util.IO;
+ import org.mortbay.util.StringUtil;
++import org.mortbay.log.Log;
++
++
+
+ /**
+ * @author gregw
+@@ -482,7 +489,52 @@ public class RequestTest extends TestCas
+ assertEquals("value7" ,cookie[7]);
+ }
+
+-
++ public void testHashDOS() throws Exception
++ {
++ _server.setAttribute("org.eclipse.jetty.server.Request.maxFormContentSize",-1);
++ _server.setAttribute("org.eclipse.jetty.server.Request.maxFormKeys",1000);
++
++ // This file is not distributed - as it is dangerous
++ File evil_keys = new File("/tmp/keys_mapping_to_zero_2m");
++ if (!evil_keys.exists())
++ {
++ Log.info("testHashDOS skipped");
++ return;
++ }
++
++ BufferedReader in = new BufferedReader(new FileReader(evil_keys));
++ StringBuilder buf = new StringBuilder(4000000);
++
++ String key=null;
++ buf.append("a=b");
++ while((key=in.readLine())!=null)
++ {
++ buf.append("&").append(key).append("=").append("x");
++ }
++ buf.append("&c=d");
++
++ _handler._checker = new RequestTester()
++ {
++ public boolean check(HttpServletRequest request,HttpServletResponse response)
++ {
++ return "b".equals(request.getParameter("a")) && request.getParameter("c")==null;
++ }
++ };
++
++ String request="POST / HTTP/1.1\r\n"+
++ "Host: whatever\r\n"+
++ "Content-Type: "+MimeTypes.FORM_ENCODED+"\r\n"+
++ "Content-Length: "+buf.length()+"\r\n"+
++ "Connection: close\r\n"+
++ "\r\n"+
++ buf;
++
++ long start=System.currentTimeMillis();
++ String response = _connector.getResponses(request);
++ assertTrue(response.contains("200 OK"));
++ long now=System.currentTimeMillis();
++ assertTrue((now-start)<5000);
++ }
+
+
+ interface RequestTester
+@@ -498,8 +550,8 @@ public class RequestTest extends TestCas
+ public void handle(String target, HttpServletRequest request, HttpServletResponse response, int dispatch) throws IOException, ServletException
+ {
+ ((Request)request).setHandled(true);
+-
+- if (request.getContentLength()>0)
++
++ if (request.getContentLength()>0 && !MimeTypes.FORM_ENCODED.equals(request.getContentType()))
+ _content=IO.toString(request.getInputStream());
+
+ if (_checker!=null && _checker.check(request,response))
+--- a/modules/util/src/main/java/org/mortbay/util/UrlEncoded.java 2012-01-16 14:47:05.000000000 -0500
++++ b/modules/util/src/main/java/org/mortbay/util/UrlEncoded.java 2012-01-16 16:59:21.000000000 -0500
+@@ -17,9 +17,11 @@ package org.mortbay.util;
+ import java.io.IOException;
+ import java.io.InputStream;
+ import java.io.InputStreamReader;
++import java.io.StringWriter;
+ import java.io.UnsupportedEncodingException;
+ import java.util.Iterator;
+ import java.util.Map;
++import org.mortbay.log.Log;
+
+
+ /* ------------------------------------------------------------ */
+@@ -73,13 +75,13 @@ public class UrlEncoded extends MultiMap
+ /* ----------------------------------------------------------------- */
+ public void decode(String query)
+ {
+- decodeTo(query,this,ENCODING);
++ decodeTo(query,this,ENCODING,-1);
+ }
+
+ /* ----------------------------------------------------------------- */
+ public void decode(String query,String charset)
+ {
+- decodeTo(query,this,charset);
++ decodeTo(query,this,charset,-1);
+ }
+
+ /* -------------------------------------------------------------- */
+@@ -174,6 +176,15 @@ public class UrlEncoded extends MultiMap
+ */
+ public static void decodeTo(String content, MultiMap map, String charset)
+ {
++ decodeTo(content,map,charset,-1);
++ }
++
++ /* -------------------------------------------------------------- */
++ /** Decoded parameters to Map.
++ * @param content the string containing the encoded parameters
++ */
++ public static void decodeTo(String content, MultiMap map, String charset, int maxKeys)
++ {
+ if (charset==null)
+ charset=ENCODING;
+
+@@ -204,6 +215,11 @@ public class UrlEncoded extends MultiMap
+ }
+ key = null;
+ value=null;
++ if (maxKeys>0 && map.size()>maxKeys)
++ {
++ Log.warn("maxFormKeys limit exceeded keys>{}",Integer.valueOf(maxKeys));
++ return;
++ }
+ break;
+ case '=':
+ if (key!=null)
+@@ -320,9 +336,10 @@ public class UrlEncoded extends MultiMap
+ /** Decoded parameters to Map.
+ * @param in InputSteam to read
+ * @param map MultiMap to add parameters to
+- * @param maxLength maximum length of content to read 0r -1 for no limit
++ * @param maxLength maximum length of content to read or -1 for no limit
++ * @param maxLength maximum number of keys to read or -1 for no limit
+ */
+- public static void decode88591To(InputStream in, MultiMap map, int maxLength)
++ public static void decode88591To(InputStream in, MultiMap map, int maxLength, int maxKeys)
+ throws IOException
+ {
+ synchronized(map)
+@@ -352,6 +369,11 @@ public class UrlEncoded extends MultiMap
+ }
+ key = null;
+ value=null;
++ if (maxKeys>0 && map.size()>maxKeys)
++ {
++ Log.warn("maxFormKeys limit exceeded keys>{}",Integer.valueOf(maxKeys));
++ return;
++ }
+ break;
+
+ case '=':
+@@ -400,9 +422,10 @@ public class UrlEncoded extends MultiMap
+ /** Decoded parameters to Map.
+ * @param in InputSteam to read
+ * @param map MultiMap to add parameters to
+- * @param maxLength maximum length of content to read 0r -1 for no limit
++ * @param maxLength maximum length of content to read or -1 for no limit
++ * @param maxLength maximum number of keys to read or -1 for no limit
+ */
+- public static void decodeUtf8To(InputStream in, MultiMap map, int maxLength)
++ public static void decodeUtf8To(InputStream in, MultiMap map, int maxLength, int maxKeys)
+ throws IOException
+ {
+ synchronized(map)
+@@ -432,6 +455,11 @@ public class UrlEncoded extends MultiMap
+ }
+ key = null;
+ value=null;
++ if (maxKeys>0 && map.size()>maxKeys)
++ {
++ Log.warn("maxFormKeys limit exceeded keys>{}",Integer.valueOf(maxKeys));
++ return;
++ }
+ break;
+
+ case '=':
+@@ -477,43 +505,38 @@ public class UrlEncoded extends MultiMap
+ }
+
+ /* -------------------------------------------------------------- */
+- public static void decodeUtf16To(InputStream in, MultiMap map, int maxLength) throws IOException
++ public static void decodeUtf16To(InputStream in, MultiMap map, int maxLength, int maxKeys) throws IOException
+ {
+ InputStreamReader input = new InputStreamReader(in,StringUtil.__UTF16);
+- StringBuffer buf = new StringBuffer();
+-
+- int c;
+- int length=0;
+- if (maxLength<0)
+- maxLength=Integer.MAX_VALUE;
+- while ((c=input.read())>0 && length++<maxLength)
+- buf.append((char)c);
+- decodeTo(buf.toString(),map,ENCODING);
++ StringWriter buf = new StringWriter(8192);
++ IO.copy(input,buf,maxLength);
++
++ decodeTo(buf.getBuffer().toString(),map,ENCODING,maxKeys);
+ }
+
+ /* -------------------------------------------------------------- */
+ /** Decoded parameters to Map.
+ * @param in the stream containing the encoded parameters
+ */
+- public static void decodeTo(InputStream in, MultiMap map, String charset, int maxLength)
++ public static void decodeTo(InputStream in, MultiMap map, String charset, int maxLength, int maxKeys)
+ throws IOException
+ {
+
+ if (charset==null || StringUtil.__UTF8.equalsIgnoreCase(charset))
+ {
+- decodeUtf8To(in,map,maxLength);
++ decodeUtf8To(in,map,maxLength,maxKeys);
+ return;
+ }
+
+ if (StringUtil.__ISO_8859_1.equals(charset))
+ {
+- decode88591To(in,map,maxLength);
++ decode88591To(in,map,maxLength,maxKeys);
+ return;
+ }
+
+ if (StringUtil.__UTF16.equalsIgnoreCase(charset)) // Should be all 2 byte encodings
+ {
+- decodeUtf16To(in,map,maxLength);
++ decodeUtf16To(in,map,maxLength,maxKeys);
+ return;
+ }
+
+--- a/modules/util/src/test/java/org/mortbay/util/URLEncodedTest.java 2012-01-16 15:19:40.000000000 -0500
++++ b/modules/util/src/test/java/org/mortbay/util/URLEncodedTest.java 2012-01-16 15:20:36.000000000 -0500
+@@ -163,7 +163,7 @@ public class URLEncodedTest extends juni
+ {
+ ByteArrayInputStream in = new ByteArrayInputStream("name\n=value+%30&name1=&name2&n\u00e3me3=value+3".getBytes(charsets[i][0]));
+ MultiMap m = new MultiMap();
+- UrlEncoded.decodeTo(in, m, charsets[i][1], -1);
++ UrlEncoded.decodeTo(in, m, charsets[i][1], -1, -1);
+ System.err.println(m);
+ assertEquals(i+" stream length",4,m.size());
+ assertEquals(i+" stream name\\n","value 0",m.getString("name\n"));
+@@ -177,7 +177,7 @@ public class URLEncodedTest extends juni
+ {
+ ByteArrayInputStream in2 = new ByteArrayInputStream ("name=%83e%83X%83g".getBytes());
+ MultiMap m2 = new MultiMap();
+- UrlEncoded.decodeTo(in2, m2, "Shift_JIS", -1);
++ UrlEncoded.decodeTo(in2, m2, "Shift_JIS", -1, -1);
+ assertEquals("stream length",1,m2.size());
+ assertEquals("stream name","\u30c6\u30b9\u30c8",m2.getString("name"));
+ }
Modified: trunk/jetty/debian/patches/series
===================================================================
--- trunk/jetty/debian/patches/series 2012-04-25 09:57:30 UTC (rev 15999)
+++ trunk/jetty/debian/patches/series 2012-04-25 10:01:33 UTC (rev 16000)
@@ -1 +1,2 @@
01_add_manifests_with_osgi_bundles_info.patch
+CVE-2011-4461.patch
More information about the pkg-java-commits
mailing list