--- java/org/apache/tomcat/util/http/fileupload/FileUploadBase.java.orig 2014-03-17 18:30:01.467636000 -0400 +++ java/org/apache/tomcat/util/http/fileupload/FileUploadBase.java 2014-03-17 18:37:43.992207000 -0400 @@ -805,7 +805,7 @@ || (!contentType.toLowerCase(Locale.ENGLISH).startsWith(MULTIPART))) { throw new InvalidContentTypeException(String.format( "the request doesn't contain a %s or %s stream, content type header is %s", - MULTIPART_FORM_DATA, MULTIPART_FORM_DATA, contentType)); + MULTIPART_FORM_DATA, MULTIPART_MIXED, contentType)); } InputStream input = ctx.getInputStream(); @@ -816,8 +816,7 @@ if (requestSize != -1 && requestSize > sizeMax) { throw new SizeLimitExceededException(String.format( "the request was rejected because its size (%s) exceeds the configured maximum (%s)", - Long.valueOf(requestSize), - Long.valueOf(sizeMax)), + Long.valueOf(requestSize), Long.valueOf(sizeMax)), requestSize, sizeMax); } input = new LimitedInputStream(input, sizeMax) { @@ -844,7 +843,14 @@ } notifier = new MultipartStream.ProgressNotifier(listener, requestSize); - multi = new MultipartStream(input, boundary, notifier); + try { + multi = new MultipartStream(input, boundary, notifier); + } catch (IllegalArgumentException iae) { + throw new InvalidContentTypeException(String.format( + "The boundary specified in the %s header is too long", + CONTENT_TYPE), iae); + } + multi.setHeaderEncoding(charEncoding); skipPreamble = true; @@ -1022,7 +1028,7 @@ * detail message. */ public InvalidContentTypeException() { - // Nothing to do. + super(); } /** @@ -1035,6 +1041,10 @@ super(message); } + public InvalidContentTypeException(String msg, Throwable cause) { + super(msg, cause); + } + } /** --- java/org/apache/tomcat/util/http/fileupload/MultipartStream.java.orig 2014-03-17 18:30:01.512626000 -0400 +++ java/org/apache/tomcat/util/http/fileupload/MultipartStream.java 2014-04-16 13:23:35.983099000 -0400 @@ -278,10 +278,9 @@ * @param pNotifier The notifier, which is used for calling the * progress listener, if any. * - * @see #MultipartStream(InputStream, byte[], - * MultipartStream.ProgressNotifier) + * @throws IllegalArgumentException If the buffer size is too small */ - MultipartStream(InputStream input, + public MultipartStream(InputStream input, byte[] boundary, int bufSize, ProgressNotifier pNotifier) { @@ -292,8 +291,12 @@ // We prepend CR/LF to the boundary to chop trailing CR/LF from // body-data tokens. - this.boundary = new byte[boundary.length + BOUNDARY_PREFIX.length]; this.boundaryLength = boundary.length + BOUNDARY_PREFIX.length; + if (bufSize < this.boundaryLength + 1) { + throw new IllegalArgumentException( + "The buffer size specified for the MultipartStream is too small"); + } + this.boundary = new byte[this.boundaryLength]; this.keepRegion = this.boundary.length; System.arraycopy(BOUNDARY_PREFIX, 0, this.boundary, 0, BOUNDARY_PREFIX.length); @@ -313,8 +316,7 @@ * @param pNotifier An object for calling the progress listener, if any. * * - * @see #MultipartStream(InputStream, byte[], int, - * MultipartStream.ProgressNotifier) + * @see #MultipartStream(InputStream, byte[], int, ProgressNotifier) */ MultipartStream(InputStream input, byte[] boundary, --- webapps/docs/changelog.xml.orig 2014-03-17 18:30:01.569656000 -0400 +++ webapps/docs/changelog.xml 2014-03-17 18:44:11.967500000 -0400 @@ -59,6 +59,11 @@ + Fix CVE-2014-0050, a denial of service with a malicious, malformed + Content-Type header and multipart request processing. Fixed by merging + latest code (r1565163) from Commons FileUpload. (markt) + + Enforce the restriction described in section 4.4 of the Servlet 3.0 specification that requires the new pluggability methods only to be available to ServletContextListeners defined in one of the