Hi, An additional vulnerability, CVE-2014-7811, has been fixed in tomcat6. A new test package is available at: deb https://people.debian.org/~santiago/debian santiago-squeeze-lts/ Cheers, Santiago P.S. I still need to fill a bug about this CVE.
diff -Nru tomcat6-6.0.41/debian/changelog tomcat6-6.0.41/debian/changelog
--- tomcat6-6.0.41/debian/changelog 2015-01-18 22:39:59.000000000 +0100
+++ tomcat6-6.0.41/debian/changelog 2015-05-22 15:45:30.000000000 +0200
@@ -1,3 +1,14 @@
+tomcat6 (6.0.41-2+squeeze7~3) santiago-squeeze-lts; urgency=medium
+
+ * Security upload by the Debian LTS team.
+ * This upload fixes the following issues:
+ - CVE-2014-0227: HTTP request smuggling or DoS by streaming malformed data.
+ - CVE-2014-0230: non-persistent DoS attack by feeding data aborting an
+ upload.
+ - CVE-2014-7810: security manager bypass by EL expressions.
+
+ -- Santiago Ruano Rincón <santiagorr@riseup.net> Fri, 22 May 2015 15:44:39 +0200
+
tomcat6 (6.0.41-2+squeeze6) squeeze-lts; urgency=medium
* Security upload by the Debian LTS team.
diff -Nru tomcat6-6.0.41/debian/patches/CVE-2014-0227.patch tomcat6-6.0.41/debian/patches/CVE-2014-0227.patch
--- tomcat6-6.0.41/debian/patches/CVE-2014-0227.patch 1970-01-01 01:00:00.000000000 +0100
+++ tomcat6-6.0.41/debian/patches/CVE-2014-0227.patch 2015-05-22 11:08:30.000000000 +0200
@@ -0,0 +1,425 @@
+Description: Improvements to ChunkedInputFilter
+ - Clean-up
+ - i18n for ChunkedInputFilter error message
+ - Add error flag to allow subsequent attempts at reading after an error to
+ fail fast
+ Fixes CVE-2014-0227
+Origin: https://svn.apache.org/viewvc?view=revision&revision=1603628
+
+Index: tomcat6-6.0.41/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java
+===================================================================
+--- tomcat6-6.0.41.orig/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java
++++ tomcat6-6.0.41/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java
+@@ -14,7 +14,6 @@
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+-
+ package org.apache.coyote.http11.filters;
+
+ import java.io.EOFException;
+@@ -29,6 +28,7 @@ import org.apache.coyote.http11.Constant
+ import org.apache.coyote.http11.InputFilter;
+ import org.apache.tomcat.util.buf.MessageBytes;
+ import org.apache.tomcat.util.http.MimeHeaders;
++import org.apache.tomcat.util.res.StringManager;
+
+ /**
+ * Chunked input filter. Parses chunked data according to
+@@ -39,9 +39,11 @@ import org.apache.tomcat.util.http.MimeH
+ */
+ public class ChunkedInputFilter implements InputFilter {
+
++ private static final StringManager sm = StringManager.getManager(
++ ChunkedInputFilter.class.getPackage().getName());
+
+- // -------------------------------------------------------------- Constants
+
++ // -------------------------------------------------------------- Constants
+
+ protected static final String ENCODING_NAME = "chunked";
+ protected static final ByteChunk ENCODING = new ByteChunk();
+@@ -49,7 +51,6 @@ public class ChunkedInputFilter implemen
+
+ // ----------------------------------------------------- Static Initializer
+
+-
+ static {
+ ENCODING.setBytes(ENCODING_NAME.getBytes(), 0, ENCODING_NAME.length());
+ }
+@@ -57,7 +58,6 @@ public class ChunkedInputFilter implemen
+
+ // ----------------------------------------------------- Instance Variables
+
+-
+ /**
+ * Next buffer in the pipeline.
+ */
+@@ -120,6 +120,11 @@ public class ChunkedInputFilter implemen
+
+
+ /**
++ * Flag that indicates if an error has occurred.
++ */
++ private boolean error;
++
++ /**
+ * Flag set to true if the next call to doRead() must parse a CRLF pair
+ * before doing anything else.
+ */
+@@ -130,13 +135,10 @@ public class ChunkedInputFilter implemen
+ * Request being parsed.
+ */
+ private Request request;
+-
+- // ------------------------------------------------------------- Properties
+
+
+ // ---------------------------------------------------- InputBuffer Methods
+
+-
+ /**
+ * Read bytes.
+ *
+@@ -146,11 +148,12 @@ public class ChunkedInputFilter implemen
+ * whichever is greater. If the filter does not do request body length
+ * control, the returned value should be -1.
+ */
+- public int doRead(ByteChunk chunk, Request req)
+- throws IOException {
+-
+- if (endChunk)
++ public int doRead(ByteChunk chunk, Request req) throws IOException {
++ if (endChunk) {
+ return -1;
++ }
++
++ checkError();
+
+ if(needCRLFParse) {
+ needCRLFParse = false;
+@@ -159,7 +162,7 @@ public class ChunkedInputFilter implemen
+
+ if (remaining <= 0) {
+ if (!parseChunkHeader()) {
+- throw new IOException("Invalid chunk header");
++ throwIOException(sm.getString("chunkedInputFilter.invalidHeader"));
+ }
+ if (endChunk) {
+ parseEndChunk();
+@@ -171,8 +174,7 @@ public class ChunkedInputFilter implemen
+
+ if (pos >= lastValid) {
+ if (readBytes() < 0) {
+- throw new IOException(
+- "Unexpected end of stream whilst reading request body");
++ throwIOException(sm.getString("chunkedInputFilter.eos"));
+ }
+ }
+
+@@ -197,13 +199,11 @@ public class ChunkedInputFilter implemen
+ }
+
+ return result;
+-
+ }
+
+
+ // ---------------------------------------------------- InputFilter Methods
+
+-
+ /**
+ * Read the content length from the request.
+ */
+@@ -215,16 +215,13 @@ public class ChunkedInputFilter implemen
+ /**
+ * End the current request.
+ */
+- public long end()
+- throws IOException {
+-
++ public long end() throws IOException {
+ // Consume extra bytes : parse the stream until the end chunk is found
+ while (doRead(readChunk, null) >= 0) {
+ }
+
+ // Return the number of extra bytes which were consumed
+- return (lastValid - pos);
+-
++ return lastValid - pos;
+ }
+
+
+@@ -232,7 +229,7 @@ public class ChunkedInputFilter implemen
+ * Amount of bytes still available in a buffer.
+ */
+ public int available() {
+- return (lastValid - pos);
++ return lastValid - pos;
+ }
+
+
+@@ -258,6 +255,7 @@ public class ChunkedInputFilter implemen
+ trailingHeaders.setLimit(org.apache.coyote.Constants.MAX_TRAILER_SIZE);
+ }
+ extensionSize = 0;
++ error = false;
+ }
+
+
+@@ -272,12 +270,10 @@ public class ChunkedInputFilter implemen
+
+ // ------------------------------------------------------ Protected Methods
+
+-
+ /**
+ * Read bytes from the previous buffer.
+ */
+- protected int readBytes()
+- throws IOException {
++ protected int readBytes() throws IOException {
+
+ int nRead = buffer.doRead(readChunk, null);
+ pos = readChunk.getStart();
+@@ -285,7 +281,6 @@ public class ChunkedInputFilter implemen
+ buf = readChunk.getBytes();
+
+ return nRead;
+-
+ }
+
+
+@@ -298,8 +293,7 @@ public class ChunkedInputFilter implemen
+ * we should not parse F23IAMGONNAMESSTHISUP34CRLF as a valid header
+ * according to spec
+ */
+- protected boolean parseChunkHeader()
+- throws IOException {
++ protected boolean parseChunkHeader() throws IOException {
+
+ int result = 0;
+ boolean eol = false;
+@@ -340,7 +334,7 @@ public class ChunkedInputFilter implemen
+ extensionSize++;
+ if (org.apache.coyote.Constants.MAX_EXTENSION_SIZE > -1 &&
+ extensionSize > org.apache.coyote.Constants.MAX_EXTENSION_SIZE) {
+- throw new IOException("maxExtensionSize exceeded");
++ throwIOException(sm.getString("chunkedInputFilter.maxExtension"));
+ }
+ }
+
+@@ -348,21 +342,22 @@ public class ChunkedInputFilter implemen
+ if (!eol) {
+ pos++;
+ }
+-
+ }
+
+- if (readDigit == 0 || result < 0)
++ if (readDigit == 0 || result < 0) {
+ return false;
++ }
+
+- if (result == 0)
++ if (result == 0) {
+ endChunk = true;
++ }
+
+ remaining = result;
+- if (remaining < 0)
++ if (remaining < 0) {
+ return false;
++ }
+
+ return true;
+-
+ }
+
+
+@@ -389,26 +384,27 @@ public class ChunkedInputFilter implemen
+ boolean crfound = false;
+
+ while (!eol) {
+-
+ if (pos >= lastValid) {
+- if (readBytes() <= 0)
+- throw new IOException("Invalid CRLF");
++ if (readBytes() <= 0) {
++ throwIOException(sm.getString("chunkedInputFilter.invalidCrlfNoData"));
++ }
+ }
+
+ if (buf[pos] == Constants.CR) {
+- if (crfound) throw new IOException("Invalid CRLF, two CR characters encountered.");
++ if (crfound) {
++ throwIOException(sm.getString("chunkedInputFilter.invalidCrlfCRCR"));
++ }
+ crfound = true;
+ } else if (buf[pos] == Constants.LF) {
+ if (!tolerant && !crfound) {
+- throw new IOException("Invalid CRLF, no CR character encountered.");
++ throwIOException(sm.getString("chunkedInputFilter.invalidCrlfNoCR"));
+ }
+ eol = true;
+ } else {
+- throw new IOException("Invalid CRLF");
++ throwIOException(sm.getString("chunkedInputFilter.invalidCrlf"));
+ }
+
+ pos++;
+-
+ }
+ }
+
+@@ -417,7 +413,6 @@ public class ChunkedInputFilter implemen
+ * Parse end chunk data.
+ */
+ protected boolean parseEndChunk() throws IOException {
+-
+ // Handle optional trailer headers
+ while (parseHeader()) {
+ // Loop until we run out of headers
+@@ -434,8 +429,9 @@ public class ChunkedInputFilter implemen
+
+ // Read new bytes if needed
+ if (pos >= lastValid) {
+- if (readBytes() <0)
+- throw new EOFException("Unexpected end of stream whilst reading trailer headers for chunked request");
++ if (readBytes() <0) {
++ throwEOFException(sm.getString("chunkedInputFilter.eosTrailer"));
++ }
+ }
+
+ chr = buf[pos];
+@@ -459,8 +455,9 @@ public class ChunkedInputFilter implemen
+
+ // Read new bytes if needed
+ if (pos >= lastValid) {
+- if (readBytes() <0)
+- throw new EOFException("Unexpected end of stream whilst reading trailer headers for chunked request");
++ if (readBytes() <0) {
++ throwEOFException(sm.getString("chunkedInputFilter.eosTrailer"));
++ }
+ }
+
+ chr = buf[pos];
+@@ -500,8 +497,9 @@ public class ChunkedInputFilter implemen
+
+ // Read new bytes if needed
+ if (pos >= lastValid) {
+- if (readBytes() <0)
+- throw new EOFException("Unexpected end of stream whilst reading trailer headers for chunked request");
++ if (readBytes() <0) {
++ throwEOFException(sm.getString("chunkedInputFilter.eosTrailer"));
++ }
+ }
+
+ chr = buf[pos];
+@@ -512,7 +510,7 @@ public class ChunkedInputFilter implemen
+ if (trailingHeaders.getLimit() != -1) {
+ int newlimit = trailingHeaders.getLimit() -1;
+ if (trailingHeaders.getEnd() > newlimit) {
+- throw new IOException("Exceeded maxTrailerSize");
++ throwIOException(sm.getString("chunkedInputFilter.maxTrailer"));
+ }
+ trailingHeaders.setLimit(newlimit);
+ }
+@@ -527,8 +525,9 @@ public class ChunkedInputFilter implemen
+
+ // Read new bytes if needed
+ if (pos >= lastValid) {
+- if (readBytes() <0)
+- throw new EOFException("Unexpected end of stream whilst reading trailer headers for chunked request");
++ if (readBytes() <0) {
++ throwEOFException(sm.getString("chunkedInputFilter.eosTrailer"));
++ }
+ }
+
+ chr = buf[pos];
+@@ -552,8 +551,9 @@ public class ChunkedInputFilter implemen
+
+ // Read new bytes if needed
+ if (pos >= lastValid) {
+- if (readBytes() <0)
+- throw new EOFException("Unexpected end of stream whilst reading trailer headers for chunked request");
++ if (readBytes() <0) {
++ throwEOFException(sm.getString("chunkedInputFilter.eosTrailer"));
++ }
+ }
+
+ chr = buf[pos];
+@@ -574,4 +574,23 @@ public class ChunkedInputFilter implemen
+
+ return true;
+ }
++
++
++ private void throwIOException(String msg) throws IOException {
++ error = true;
++ throw new IOException(msg);
++ }
++
++
++ private void throwEOFException(String msg) throws IOException {
++ error = true;
++ throw new EOFException(msg);
++ }
++
++
++ private void checkError() throws IOException {
++ if (error) {
++ throw new IOException(sm.getString("chunkedInputFilter.error"));
++ }
++ }
+ }
+Index: tomcat6-6.0.41/java/org/apache/coyote/http11/filters/LocalStrings.properties
+===================================================================
+--- /dev/null
++++ tomcat6-6.0.41/java/org/apache/coyote/http11/filters/LocalStrings.properties
+@@ -0,0 +1,25 @@
++# Licensed to the Apache Software Foundation (ASF) under one or more
++# contributor license agreements. See the NOTICE file distributed with
++# this work for additional information regarding copyright ownership.
++# The ASF licenses this file to You under the Apache License, Version 2.0
++# (the "License"); you may not use this file except in compliance with
++# the License. You may obtain a copy of the License at
++#
++# http://www.apache.org/licenses/LICENSE-2.0
++#
++# Unless required by applicable law or agreed to in writing, software
++# distributed under the License is distributed on an "AS IS" BASIS,
++# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
++# See the License for the specific language governing permissions and
++# limitations under the License.
++
++chunkedInputFilter.error=No data available due to previous error
++chunkedInputFilter.eos=Unexpected end of stream while reading request body
++chunkedInputFilter.eosTrailer=Unexpected end of stream while reading trailer headers
++chunkedInputFilter.invalidCrlf=Invalid end of line sequence (character other than CR or LF found)
++chunkedInputFilter.invalidCrlfCRCR=Invalid end of line sequence (CRCR)
++chunkedInputFilter.invalidCrlfNoCR=Invalid end of line sequence (No CR before LF)
++chunkedInputFilter.invalidCrlfNoData=Invalid end of line sequence (no data available to read)
++chunkedInputFilter.invalidHeader=Invalid chunk header
++chunkedInputFilter.maxExtension=maxExtensionSize exceeded
++chunkedInputFilter.maxTrailer=maxTrailerSize exceeded
+\ No newline at end of file
+Index: tomcat6-6.0.41/webapps/docs/changelog.xml
+===================================================================
+--- tomcat6-6.0.41.orig/webapps/docs/changelog.xml
++++ tomcat6-6.0.41/webapps/docs/changelog.xml
+@@ -272,6 +272,15 @@
+ </fix>
+ </changelog>
+ </subsection>
++ <subsection name="Coyote">
++ <changelog>
++ <fix>
++ Various improvements to ChunkedInputFilter including clean-up, i18n for
++ error messages and adding an error flag to allow subsequent attempts at
++ reading after an error to fail fast. (markt)
++ </fix>
++ </changelog>
++ </subsection>
+ <subsection name="Jasper">
+ <changelog>
+ <fix>
diff -Nru tomcat6-6.0.41/debian/patches/CVE-2014-0230.patch tomcat6-6.0.41/debian/patches/CVE-2014-0230.patch
--- tomcat6-6.0.41/debian/patches/CVE-2014-0230.patch 1970-01-01 01:00:00.000000000 +0100
+++ tomcat6-6.0.41/debian/patches/CVE-2014-0230.patch 2015-05-22 11:08:34.000000000 +0200
@@ -0,0 +1,148 @@
+Description: Add support for maxSwallowSize
+ Fixes CVE-2014-0230
+Origin: https://svn.apache.org/viewvc?view=revision&revision=1659537
+
+Index: tomcat6-6.0.41/java/org/apache/coyote/http11/filters/IdentityInputFilter.java
+===================================================================
+--- tomcat6-6.0.41.orig/java/org/apache/coyote/http11/filters/IdentityInputFilter.java
++++ tomcat6-6.0.41/java/org/apache/coyote/http11/filters/IdentityInputFilter.java
+@@ -20,7 +20,7 @@ package org.apache.coyote.http11.filters
+ import java.io.IOException;
+
+ import org.apache.tomcat.util.buf.ByteChunk;
+-
++import org.apache.tomcat.util.res.StringManager;
+ import org.apache.coyote.InputBuffer;
+ import org.apache.coyote.Request;
+ import org.apache.coyote.http11.InputFilter;
+@@ -32,9 +32,11 @@ import org.apache.coyote.http11.InputFil
+ */
+ public class IdentityInputFilter implements InputFilter {
+
++ private static final StringManager sm = StringManager.getManager(
++ IdentityInputFilter.class.getPackage().getName());
+
+- // -------------------------------------------------------------- Constants
+
++ // -------------------------------------------------------------- Constants
+
+ protected static final String ENCODING_NAME = "identity";
+ protected static final ByteChunk ENCODING = new ByteChunk();
+@@ -150,17 +152,25 @@ public class IdentityInputFilter impleme
+ }
+
+
+- /**
+- * End the current request.
+- */
+- public long end()
+- throws IOException {
++ public long end() throws IOException {
++
++ final int maxSwallowSize = org.apache.coyote.Constants.MAX_SWALLOW_SIZE;
++ final boolean maxSwallowSizeExceeded = (maxSwallowSize > -1 && remaining > maxSwallowSize);
++ long swallowed = 0;
+
+ // Consume extra bytes.
+ while (remaining > 0) {
++
+ int nread = buffer.doRead(endChunk, null);
+ if (nread > 0 ) {
++ swallowed += nread;
+ remaining = remaining - nread;
++ if (maxSwallowSizeExceeded && swallowed > maxSwallowSize) {
++ // Note: We do not fail early so the client has a chance to
++ // read the response before the connection is closed. See:
++ // http://httpd.apache.org/docs/2.0/misc/fin_wait_2.html#appendix
++ throw new IOException(sm.getString("inputFilter.maxSwallow"));
++ }
+ } else { // errors are handled higher up.
+ remaining = 0;
+ }
+Index: tomcat6-6.0.41/java/org/apache/coyote/http11/filters/LocalStrings.properties
+===================================================================
+--- tomcat6-6.0.41.orig/java/org/apache/coyote/http11/filters/LocalStrings.properties
++++ tomcat6-6.0.41/java/org/apache/coyote/http11/filters/LocalStrings.properties
+@@ -22,4 +22,6 @@ chunkedInputFilter.invalidCrlfNoCR=Inval
+ chunkedInputFilter.invalidCrlfNoData=Invalid end of line sequence (no data available to read)
+ chunkedInputFilter.invalidHeader=Invalid chunk header
+ chunkedInputFilter.maxExtension=maxExtensionSize exceeded
+-chunkedInputFilter.maxTrailer=maxTrailerSize exceeded
+\ No newline at end of file
++chunkedInputFilter.maxTrailer=maxTrailerSize exceeded
++
++inputFilter.maxSwallow=maxSwallowSize exceeded
+Index: tomcat6-6.0.41/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java
+===================================================================
+--- tomcat6-6.0.41.orig/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java
++++ tomcat6-6.0.41/java/org/apache/coyote/http11/filters/ChunkedInputFilter.java
+@@ -216,8 +216,15 @@ public class ChunkedInputFilter implemen
+ * End the current request.
+ */
+ public long end() throws IOException {
++ int maxSwallowSize = org.apache.coyote.Constants.MAX_SWALLOW_SIZE;
++ long swallowed = 0;
++ int read = 0;
+ // Consume extra bytes : parse the stream until the end chunk is found
+- while (doRead(readChunk, null) >= 0) {
++ while ((read = doRead(readChunk, null)) >= 0) {
++ swallowed += read;
++ if (maxSwallowSize > -1 && swallowed > maxSwallowSize) {
++ throwIOException(sm.getString("inputFilter.maxSwallow"));
++ }
+ }
+
+ // Return the number of extra bytes which were consumed
+Index: tomcat6-6.0.41/java/org/apache/coyote/Constants.java
+===================================================================
+--- tomcat6-6.0.41.orig/java/org/apache/coyote/Constants.java
++++ tomcat6-6.0.41/java/org/apache/coyote/Constants.java
+@@ -85,4 +85,13 @@ public final class Constants {
+ Integer.parseInt(System.getProperty(
+ "org.apache.coyote.MAX_EXTENSION_SIZE",
+ "8192"));
++
++ /**
++ * Limit on the length of request body Tomcat will swallow if it is not
++ * read during normal request processing. Defaults to 2MB.
++ */
++ public static final int MAX_SWALLOW_SIZE =
++ Integer.parseInt(System.getProperty(
++ "org.apache.coyote.MAX_SWALLOW_SIZE",
++ "2097152"));
+ }
+Index: tomcat6-6.0.41/webapps/docs/changelog.xml
+===================================================================
+--- tomcat6-6.0.41.orig/webapps/docs/changelog.xml
++++ tomcat6-6.0.41/webapps/docs/changelog.xml
+@@ -51,6 +51,11 @@
+ attributes with empty string value in custom tags. Based on a patch
+ provided by Hariprasad Manchi. (violetagg/kkolinko)
+ </fix>
++ <fix>
++ When applying the <code>maxSwallowSize</code> limit to a connection read
++ that many bytes first before closing the connection to give the client a
++ chance to read the reponse. (markt)
++ </fix>
+ </changelog>
+ </subsection>
+ </section>
+Index: tomcat6-6.0.41/webapps/docs/config/systemprops.xml
+===================================================================
+--- tomcat6-6.0.41.orig/webapps/docs/config/systemprops.xml
++++ tomcat6-6.0.41/webapps/docs/config/systemprops.xml
+@@ -440,6 +440,14 @@
+ <p>If not specified, the default value of <code>8192</code> will be used.</p>
+ </property>
+
++ <property name="org.apache.coyote.MAX_SWALLOW_SIZE">
++ <p>Limits the length of a request body Tomcat will swallow if it is not
++ read during normal request processing. If the value is <code>-1</code>, no
++ limit will be imposed.</p>
++ <p>If not specified, the default value of <code>2097152</code> (2MB) will
++ be used.</p>
++ </property>
++
+ <property name="catalina.useNaming">
+ <p>If this is <code>false</code> it will override the
+ <code>useNaming</code> attribute for all <a href="context.html">
diff -Nru tomcat6-6.0.41/debian/patches/CVE-2014-7810-1.patch tomcat6-6.0.41/debian/patches/CVE-2014-7810-1.patch
--- tomcat6-6.0.41/debian/patches/CVE-2014-7810-1.patch 1970-01-01 01:00:00.000000000 +0100
+++ tomcat6-6.0.41/debian/patches/CVE-2014-7810-1.patch 2015-05-22 15:00:49.000000000 +0200
@@ -0,0 +1,92 @@
+Description: Fix potential BeanELResolver issue when running under a security manager.
+ Some classes may not be accessible but may have accessible interfaces.
+ This is part of the fix for CVE-2014-7810
+Origin: http://svn.apache.org/viewvc?view=revision&revision=1645366
+
+--- a/java/javax/el/BeanELResolver.java
++++ b/java/javax/el/BeanELResolver.java
+@@ -188,25 +188,49 @@
+ return null;
+ }
+
+- protected final static class BeanProperties {
+- private final Map<String, BeanProperty> properties;
++ protected final static class BeanProperties {
++ private final Map<String, BeanProperty> properties;
+
+- private final Class<?> type;
++ private final Class<?> type;
+
+- public BeanProperties(Class<?> type) throws ELException {
+- this.type = type;
+- this.properties = new HashMap<String, BeanProperty>();
+- try {
+- BeanInfo info = Introspector.getBeanInfo(this.type);
+- PropertyDescriptor[] pds = info.getPropertyDescriptors();
+- for (int i = 0; i < pds.length; i++) {
+- this.properties.put(pds[i].getName(), new BeanProperty(
+- type, pds[i]));
+- }
+- } catch (IntrospectionException ie) {
+- throw new ELException(ie);
+- }
+- }
++ public BeanProperties(Class<?> type) throws ELException {
++ this.type = type;
++ this.properties = new HashMap<String, BeanProperty>();
++ try {
++ BeanInfo info = Introspector.getBeanInfo(this.type);
++ PropertyDescriptor[] pds = info.getPropertyDescriptors();
++ for (PropertyDescriptor pd: pds) {
++ this.properties.put(pd.getName(), new BeanProperty(type, pd));
++ }
++ if (System.getSecurityManager() != null) {
++ // When running with SecurityManager, some classes may be
++ // not accessible, but have accessible interfaces.
++ populateFromInterfaces(type);
++ }
++ } catch (IntrospectionException ie) {
++ throw new ELException(ie);
++ }
++ }
++
++ private void populateFromInterfaces(Class<?> aClass) throws IntrospectionException {
++ Class<?> interfaces[] = aClass.getInterfaces();
++ if (interfaces.length > 0) {
++ for (Class<?> ifs : interfaces) {
++ BeanInfo info = Introspector.getBeanInfo(ifs);
++ PropertyDescriptor[] pds = info.getPropertyDescriptors();
++ for (PropertyDescriptor pd : pds) {
++ if (!this.properties.containsKey(pd.getName())) {
++ this.properties.put(pd.getName(), new BeanProperty(
++ this.type, pd));
++ }
++ }
++ }
++ }
++ Class<?> superclass = aClass.getSuperclass();
++ if (superclass != null) {
++ populateFromInterfaces(superclass);
++ }
++ }
+
+ private BeanProperty get(ELContext ctx, String name) {
+ BeanProperty property = this.properties.get(name);
+--- a/webapps/docs/changelog.xml
++++ b/webapps/docs/changelog.xml
+@@ -952,6 +952,15 @@
+ </fix>
+ </changelog>
+ </subsection>
++ <subsection name="Jasper">
++ <changelog>
++ <fix>
++ Fix potential issue with BeanELResolver when running under a security
++ manager. Some classes may not be accessible but may have accessible
++ interfaces. (markt)
++ </fix>
++ </changelog>
++ </subsection>
+ <subsection name="Web applications">
+ <changelog>
+ <fix>
diff -Nru tomcat6-6.0.41/debian/patches/CVE-2014-7810-2.patch tomcat6-6.0.41/debian/patches/CVE-2014-7810-2.patch
--- tomcat6-6.0.41/debian/patches/CVE-2014-7810-2.patch 1970-01-01 01:00:00.000000000 +0100
+++ tomcat6-6.0.41/debian/patches/CVE-2014-7810-2.patch 2015-05-22 15:42:16.000000000 +0200
@@ -0,0 +1,136 @@
+Description: Backport some Jasper clean-up that might provide a marginal performance improvement.
+ Even if it doesn't it removes some unnecessary code.
+ This is part of the fix for CVE-2014-7810
+Origin: http://svn.apache.org/viewvc?view=revision&revision=1659538
+
+--- a/java/org/apache/jasper/runtime/PageContextImpl.java
++++ b/java/org/apache/jasper/runtime/PageContextImpl.java
+@@ -5,9 +5,9 @@
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+- *
++ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+- *
++ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+@@ -59,7 +59,7 @@
+ /**
+ * Implementation of the PageContext class from the JSP spec. Also doubles as a
+ * VariableResolver for the EL.
+- *
++ *
+ * @author Anil K. Vijendran
+ * @author Larry Cable
+ * @author Hans Bergsten
+@@ -70,7 +70,7 @@
+ */
+ public class PageContextImpl extends PageContext {
+
+- private static final JspFactory jspf = JspFactory.getDefaultFactory();
++ private static final JspFactory jspf = JspFactory.getDefaultFactory();
+
+ private BodyContentImpl[] outs;
+
+@@ -96,12 +96,12 @@
+ private transient ServletResponse response;
+
+ private transient HttpSession session;
+-
++
+ private transient ELContextImpl elContext;
+
+ private boolean isIncluded;
+-
+-
++
++
+ // initial output stream
+ private transient JspWriter out;
+
+@@ -137,7 +137,7 @@
+ this.errorPageURL = errorPageURL;
+ this.request = request;
+ this.response = response;
+-
++
+ // initialize application context
+ this.applicationContext = JspApplicationContextImpl.getInstance(context);
+
+@@ -589,7 +589,7 @@
+ * Returns the exception associated with this page context, if any. <p/>
+ * Added wrapping for Throwables to avoid ClassCastException: see Bugzilla
+ * 31171 for details.
+- *
++ *
+ * @return The Exception associated with this page context, if any.
+ */
+ public Exception getException() {
+@@ -875,7 +875,7 @@
+ * go away once the EL interpreter moves out of JSTL and into its own
+ * project. For now, this is necessary because the standard machinery is too
+ * slow.
+- *
++ *
+ * @param expression
+ * The expression to be evaluated
+ * @param expectedType
+@@ -887,39 +887,14 @@
+ * @return The result of the evaluation
+ */
+ public static Object proprietaryEvaluate(final String expression,
+- final Class expectedType, final PageContext pageContext,
++ final Class<?> expectedType, final PageContext pageContext,
+ final ProtectedFunctionMapper functionMap, final boolean escape)
+ throws ELException {
+- Object retValue;
+ final ExpressionFactory exprFactory = jspf.getJspApplicationContext(pageContext.getServletContext()).getExpressionFactory();
+- if (SecurityUtil.isPackageProtectionEnabled()) {
+- try {
+- retValue = AccessController
+- .doPrivileged(new PrivilegedExceptionAction() {
+-
+- public Object run() throws Exception {
+- ELContextImpl ctx = (ELContextImpl) pageContext.getELContext();
+- ctx.setFunctionMapper(new FunctionMapperImpl(functionMap));
+- ValueExpression ve = exprFactory.createValueExpression(ctx, expression, expectedType);
+- return ve.getValue(ctx);
+- }
+- });
+- } catch (PrivilegedActionException ex) {
+- Exception realEx = ex.getException();
+- if (realEx instanceof ELException) {
+- throw (ELException) realEx;
+- } else {
+- throw new ELException(realEx);
+- }
+- }
+- } else {
+- ELContextImpl ctx = (ELContextImpl) pageContext.getELContext();
+- ctx.setFunctionMapper(new FunctionMapperImpl(functionMap));
+- ValueExpression ve = exprFactory.createValueExpression(ctx, expression, expectedType);
+- retValue = ve.getValue(ctx);
+- }
+-
+- return retValue;
++ ELContextImpl ctx = (ELContextImpl) pageContext.getELContext();
++ ctx.setFunctionMapper(new FunctionMapperImpl(functionMap));
++ ValueExpression ve = exprFactory.createValueExpression(ctx, expression, expectedType);
++ return ve.getValue(ctx);
+ }
+
+ public ELContext getELContext() {
+--- a/java/org/apache/jasper/security/SecurityClassLoad.java
++++ b/java/org/apache/jasper/security/SecurityClassLoad.java
+@@ -93,8 +93,6 @@
+ "runtime.PageContextImpl$11");
+ loader.loadClass( basePackage +
+ "runtime.PageContextImpl$12");
+- loader.loadClass( basePackage +
+- "runtime.PageContextImpl$13");
+
+ loader.loadClass( basePackage +
+ "runtime.JspContextWrapper");
diff -Nru tomcat6-6.0.41/debian/patches/series tomcat6-6.0.41/debian/patches/series
--- tomcat6-6.0.41/debian/patches/series 2015-01-18 22:39:58.000000000 +0100
+++ tomcat6-6.0.41/debian/patches/series 2015-05-22 13:14:57.000000000 +0200
@@ -8,3 +8,7 @@
0008-add-OSGI-headers-to-jsp-api.patch
0010-Use-java.security.policy-file-in-catalina.sh.patch
0011-Fix-for-NoSuchElementException-when-an-attribute-has.patch
+CVE-2014-0227.patch
+CVE-2014-0230.patch
+CVE-2014-7810-1.patch
+CVE-2014-7810-2.patch
Attachment:
signature.asc
Description: Digital signature