[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

tomcat6 squeeze-lts packages available for test, CVE-2014-7810



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


Reply to: