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

tomcat6 squeeze-lts packages available for test, CVE-2014-0227 and CVE-2014-0230



Hi,

I've prepared a tomcat6 package with the patches I've recently submitted
to the BTS concerning  CVE-2014-0227 and CVE-2014-0230. I haven't found
a test-case for the CVEs and I have been unable to test the
vulnerability by myself. Although, I have tested the basic tomcat6
functionnalities.

The packages are available at the repository:
deb https://people.debian.org/~santiago/debian santiago-squeeze-lts/

Regards,

Santiago
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-15 10:39:02.000000000 +0200
@@ -1,3 +1,13 @@
+tomcat6 (6.0.41-2+squeeze7~2) 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
+
+ -- Santiago Ruano Rincón <santiago@riseup.net>  Fri, 15 May 2015 10:38:49 +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-14 15:44:49.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-14 15:48:21.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/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-14 14:11:17.000000000 +0200
@@ -8,3 +8,5 @@
 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

Attachment: signature.asc
Description: Digital signature


Reply to: