Hi, I've forward ported Thorsten's fix fow squeeze to wheezy and added some autopkgtest (debdiff attached). Please find the debdiff attached. I'd be happy to upload ths to security master. Cheers, -- Guido
diff --git a/debian/changelog b/debian/changelog index b52643b..b6c42f0 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +polarssl (1.2.9-1~deb7u6) wheezy-security; urgency=high + + * Non-maintainer upload by the LTS Security Team. + * CVE-2015-5291: Remote attack on clients using session tickets or SNI + + -- Guido Günther <a...@sigxcpu.org> Sat, 23 Jan 2016 15:47:29 +0100 + polarssl (1.2.9-1~deb7u5) wheezy-security; urgency=high * Non-maintainer upload by the Security Team. diff --git a/debian/patches/CVE-2015-5291-1.patch b/debian/patches/CVE-2015-5291-1.patch new file mode 100644 index 0000000..f1dc35c --- /dev/null +++ b/debian/patches/CVE-2015-5291-1.patch @@ -0,0 +1,27 @@ +Index: polarssl-1.2.9/include/polarssl/ssl.h +=================================================================== +--- polarssl-1.2.9.orig/include/polarssl/ssl.h 2015-10-22 15:42:52.000000000 +0200 ++++ polarssl-1.2.9/include/polarssl/ssl.h 2015-10-22 15:44:14.000000000 +0200 +@@ -123,6 +123,8 @@ + #define SSL_LEGACY_ALLOW_RENEGOTIATION 1 + #define SSL_LEGACY_BREAK_HANDSHAKE 2 + ++#define SSL_MAX_HOST_NAME_LEN 255 /*!< Maximum host name defined in RFC 1035 */ ++ + /* + * Size of the input / output buffer. + * Note: the RFC defines the default size of SSL / TLS messages. If you +Index: polarssl-1.2.9/library/ssl_tls.c +=================================================================== +--- polarssl-1.2.9.orig/library/ssl_tls.c 2015-10-22 15:42:52.000000000 +0200 ++++ polarssl-1.2.9/library/ssl_tls.c 2015-10-22 15:45:02.000000000 +0200 +@@ -3260,6 +3260,9 @@ + if( ssl->hostname_len + 1 == 0 ) + return( POLARSSL_ERR_SSL_BAD_INPUT_DATA ); + ++ if( ssl->hostname_len > SSL_MAX_HOST_NAME_LEN ) ++ return( POLARSSL_ERR_SSL_BAD_INPUT_DATA ); ++ + ssl->hostname = (unsigned char *) malloc( ssl->hostname_len + 1 ); + + if( ssl->hostname == NULL ) diff --git a/debian/patches/series b/debian/patches/series index 929750e..06dd432 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -5,3 +5,11 @@ CVE-2014-4911.patch CVE-2014-8628.patch CVE-2015-1182.patch + +# fix for CVE-2015-5291 +# -> https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2015-5291 +CVE-2015-5291-1.patch +# vulnerable code not present +#CVE-2015-5291-2.patch +#CVE-2015-5291-3.patch +#CVE-2015-5291-4.patch diff --git a/debian/patches/vulernable-code-not-present/CVE-2015-5291-2.patch b/debian/patches/vulernable-code-not-present/CVE-2015-5291-2.patch new file mode 100644 index 0000000..f4d43ee --- /dev/null +++ b/debian/patches/vulernable-code-not-present/CVE-2015-5291-2.patch @@ -0,0 +1,323 @@ +diff --git a/library/ssl_cli.c b/library/ssl_cli.c +index f603cff..deeee33 100644 +--- a/library/ssl_cli.c ++++ b/library/ssl_cli.c +@@ -65,6 +65,7 @@ static void ssl_write_hostname_ext( ssl_context *ssl, + size_t *olen ) + { + unsigned char *p = buf; ++ const unsigned char *end = ssl->out_msg + SSL_MAX_CONTENT_LEN; + + *olen = 0; + +@@ -74,6 +75,12 @@ static void ssl_write_hostname_ext( ssl_context *ssl, + SSL_DEBUG_MSG( 3, ( "client hello, adding server name extension: %s", + ssl->hostname ) ); + ++ if( (size_t)(end - p) < ssl->hostname_len + 9 ) ++ { ++ SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); ++ return; ++ } ++ + /* + * struct { + * NameType name_type; +@@ -117,6 +124,7 @@ static void ssl_write_renegotiation_ext( ssl_context *ssl, + size_t *olen ) + { + unsigned char *p = buf; ++ const unsigned char *end = ssl->out_msg + SSL_MAX_CONTENT_LEN; + + *olen = 0; + +@@ -125,6 +133,12 @@ static void ssl_write_renegotiation_ext( ssl_context *ssl, + + SSL_DEBUG_MSG( 3, ( "client hello, adding renegotiation extension" ) ); + ++ if( (size_t)(end - p) < 5 + ssl->verify_data_len ) ++ { ++ SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); ++ return; ++ } ++ + /* + * Secure renegotiation + */ +@@ -151,6 +165,7 @@ static void ssl_write_signature_algorithms_ext( ssl_context *ssl, + size_t *olen ) + { + unsigned char *p = buf; ++ const unsigned char *end = ssl->out_msg + SSL_MAX_CONTENT_LEN; + size_t sig_alg_len = 0; + #if defined(POLARSSL_RSA_C) || defined(POLARSSL_ECDSA_C) + unsigned char *sig_alg_list = buf + 6; +@@ -163,9 +178,54 @@ static void ssl_write_signature_algorithms_ext( ssl_context *ssl, + + SSL_DEBUG_MSG( 3, ( "client hello, adding signature_algorithms extension" ) ); + ++#if defined(POLARSSL_RSA_C) ++#if defined(POLARSSL_SHA512_C) ++ /* SHA512 + RSA signature, SHA384 + RSA signature */ ++ sig_alg_len += 4; ++#endif ++#if defined(POLARSSL_SHA256_C) ++ /* SHA256 + RSA signature, SHA224 + RSA signature */ ++ sig_alg_len += 4; ++#endif ++#if defined(POLARSSL_SHA1_C) ++ /* SHA1 + RSA signature */ ++ sig_alg_len += 2; ++#endif ++#if defined(POLARSSL_MD5_C) ++ /* MD5 + RSA signature */ ++ sig_alg_len += 2; ++#endif ++#endif /* POLARSSL_RSA_C */ ++#if defined(POLARSSL_ECDSA_C) ++#if defined(POLARSSL_SHA512_C) ++ /* SHA512 + ECDSA signature, SHA384 + ECDSA signature */ ++ sig_alg_len += 4; ++#endif ++#if defined(POLARSSL_SHA256_C) ++ /* SHA256 + ECDSA signature, SHA224 + ECDSA signature */ ++ sig_alg_len += 4; ++#endif ++#if defined(POLARSSL_SHA1_C) ++ /* SHA1 + ECDSA signature */ ++ sig_alg_len += 2; ++#endif ++#if defined(POLARSSL_MD5_C) ++ /* MD5 + ECDSA signature */ ++ sig_alg_len += 2; ++#endif ++#endif /* POLARSSL_ECDSA_C */ ++ ++ if( end < p || (size_t)( end - p ) < sig_alg_len + 6 ) ++ { ++ SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); ++ return; ++ } ++ + /* + * Prepare signature_algorithms extension (TLS 1.2) + */ ++ sig_alg_len = 0; ++ + #if defined(POLARSSL_RSA_C) + #if defined(POLARSSL_SHA512_C) + sig_alg_list[sig_alg_len++] = SSL_HASH_SHA512; +@@ -248,6 +308,7 @@ static void ssl_write_supported_elliptic_curves_ext( ssl_context *ssl, + size_t *olen ) + { + unsigned char *p = buf; ++ const unsigned char *end = ssl->out_msg + SSL_MAX_CONTENT_LEN; + unsigned char *elliptic_curve_list = p + 6; + size_t elliptic_curve_len = 0; + const ecp_curve_info *info; +@@ -269,6 +330,25 @@ static void ssl_write_supported_elliptic_curves_ext( ssl_context *ssl, + for( info = ecp_curve_list(); info->grp_id != POLARSSL_ECP_DP_NONE; info++ ) + { + #endif ++ elliptic_curve_len += 2; ++ } ++ ++ if( end < p || (size_t)( end - p ) < 6 + elliptic_curve_len ) ++ { ++ SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); ++ return; ++ } ++ ++ elliptic_curve_len = 0; ++ ++#if defined(POLARSSL_SSL_SET_CURVES) ++ for( grp_id = ssl->curve_list; *grp_id != POLARSSL_ECP_DP_NONE; grp_id++ ) ++ { ++ info = ecp_curve_info_from_grp_id( *grp_id ); ++#else ++ for( info = ecp_curve_list(); info->grp_id != POLARSSL_ECP_DP_NONE; info++ ) ++ { ++#endif + + elliptic_curve_list[elliptic_curve_len++] = info->tls_id >> 8; + elliptic_curve_list[elliptic_curve_len++] = info->tls_id & 0xFF; +@@ -294,12 +374,18 @@ static void ssl_write_supported_point_formats_ext( ssl_context *ssl, + size_t *olen ) + { + unsigned char *p = buf; +- ((void) ssl); ++ const unsigned char *end = ssl->out_msg + SSL_MAX_CONTENT_LEN; + + *olen = 0; + + SSL_DEBUG_MSG( 3, ( "client hello, adding supported_point_formats extension" ) ); + ++ if( end < p || (size_t)( end - p ) < 6 ) ++ { ++ SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); ++ return; ++ } ++ + *p++ = (unsigned char)( ( TLS_EXT_SUPPORTED_POINT_FORMATS >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( TLS_EXT_SUPPORTED_POINT_FORMATS ) & 0xFF ); + +@@ -319,14 +405,21 @@ static void ssl_write_max_fragment_length_ext( ssl_context *ssl, + size_t *olen ) + { + unsigned char *p = buf; ++ const unsigned char *end = ssl->out_msg + SSL_MAX_CONTENT_LEN; + +- if( ssl->mfl_code == SSL_MAX_FRAG_LEN_NONE ) { +- *olen = 0; ++ *olen = 0; ++ ++ if( ssl->mfl_code == SSL_MAX_FRAG_LEN_NONE ) + return; +- } + + SSL_DEBUG_MSG( 3, ( "client hello, adding max_fragment_length extension" ) ); + ++ if( end < p || (size_t)( end - p ) < 5 ) ++ { ++ SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); ++ return; ++ } ++ + *p++ = (unsigned char)( ( TLS_EXT_MAX_FRAGMENT_LENGTH >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( TLS_EXT_MAX_FRAGMENT_LENGTH ) & 0xFF ); + +@@ -344,15 +437,21 @@ static void ssl_write_truncated_hmac_ext( ssl_context *ssl, + unsigned char *buf, size_t *olen ) + { + unsigned char *p = buf; ++ const unsigned char *end = ssl->out_msg + SSL_MAX_CONTENT_LEN; ++ ++ *olen = 0; + + if( ssl->trunc_hmac == SSL_TRUNC_HMAC_DISABLED ) +- { +- *olen = 0; + return; +- } + + SSL_DEBUG_MSG( 3, ( "client hello, adding truncated_hmac extension" ) ); + ++ if( end < p || (size_t)( end - p ) < 4 ) ++ { ++ SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); ++ return; ++ } ++ + *p++ = (unsigned char)( ( TLS_EXT_TRUNCATED_HMAC >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( TLS_EXT_TRUNCATED_HMAC ) & 0xFF ); + +@@ -368,17 +467,25 @@ static void ssl_write_encrypt_then_mac_ext( ssl_context *ssl, + unsigned char *buf, size_t *olen ) + { + unsigned char *p = buf; ++ const unsigned char *end = ssl->out_msg + SSL_MAX_CONTENT_LEN; ++ ++ *olen = 0; + + if( ssl->encrypt_then_mac == SSL_ETM_DISABLED || + ssl->max_minor_ver == SSL_MINOR_VERSION_0 ) + { +- *olen = 0; + return; + } + + SSL_DEBUG_MSG( 3, ( "client hello, adding encrypt_then_mac " + "extension" ) ); + ++ if( end < p || (size_t)( end - p ) < 4 ) ++ { ++ SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); ++ return; ++ } ++ + *p++ = (unsigned char)( ( TLS_EXT_ENCRYPT_THEN_MAC >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( TLS_EXT_ENCRYPT_THEN_MAC ) & 0xFF ); + +@@ -394,17 +501,25 @@ static void ssl_write_extended_ms_ext( ssl_context *ssl, + unsigned char *buf, size_t *olen ) + { + unsigned char *p = buf; ++ const unsigned char *end = ssl->out_msg + SSL_MAX_CONTENT_LEN; ++ ++ *olen = 0; + + if( ssl->extended_ms == SSL_EXTENDED_MS_DISABLED || + ssl->max_minor_ver == SSL_MINOR_VERSION_0 ) + { +- *olen = 0; + return; + } + + SSL_DEBUG_MSG( 3, ( "client hello, adding extended_master_secret " + "extension" ) ); + ++ if( end < p || (size_t)( end - p ) < 4 ) ++ { ++ SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); ++ return; ++ } ++ + *p++ = (unsigned char)( ( TLS_EXT_EXTENDED_MASTER_SECRET >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( TLS_EXT_EXTENDED_MASTER_SECRET ) & 0xFF ); + +@@ -420,16 +535,22 @@ static void ssl_write_session_ticket_ext( ssl_context *ssl, + unsigned char *buf, size_t *olen ) + { + unsigned char *p = buf; ++ const unsigned char *end = ssl->out_msg + SSL_MAX_CONTENT_LEN; + size_t tlen = ssl->session_negotiate->ticket_len; + ++ *olen = 0; ++ + if( ssl->session_tickets == SSL_SESSION_TICKETS_DISABLED ) +- { +- *olen = 0; + return; +- } + + SSL_DEBUG_MSG( 3, ( "client hello, adding session ticket extension" ) ); + ++ if( end < p || (size_t)( end - p ) < 4 + tlen ) ++ { ++ SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); ++ return; ++ } ++ + *p++ = (unsigned char)( ( TLS_EXT_SESSION_TICKET >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( TLS_EXT_SESSION_TICKET ) & 0xFF ); + +@@ -457,16 +578,26 @@ static void ssl_write_alpn_ext( ssl_context *ssl, + unsigned char *buf, size_t *olen ) + { + unsigned char *p = buf; ++ const unsigned char *end = ssl->out_msg + SSL_MAX_CONTENT_LEN; ++ size_t alpnlen = 0; + const char **cur; + ++ *olen = 0; ++ + if( ssl->alpn_list == NULL ) +- { +- *olen = 0; + return; +- } + + SSL_DEBUG_MSG( 3, ( "client hello, adding alpn extension" ) ); + ++ for( cur = ssl->alpn_list; *cur != NULL; cur++ ) ++ alpnlen += (unsigned char)( strlen( *cur ) & 0xFF ) + 1; ++ ++ if( end < p || (size_t)( end - p ) < 6 + alpnlen ) ++ { ++ SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); ++ return; ++ } ++ + *p++ = (unsigned char)( ( TLS_EXT_ALPN >> 8 ) & 0xFF ); + *p++ = (unsigned char)( ( TLS_EXT_ALPN ) & 0xFF ); + diff --git a/debian/patches/vulernable-code-not-present/CVE-2015-5291-3.patch b/debian/patches/vulernable-code-not-present/CVE-2015-5291-3.patch new file mode 100644 index 0000000..52a0f4a --- /dev/null +++ b/debian/patches/vulernable-code-not-present/CVE-2015-5291-3.patch @@ -0,0 +1,51 @@ +diff --git a/ChangeLog b/ChangeLog +index 44f4408..ddba5c0 100644 +--- a/ChangeLog ++++ b/ChangeLog +@@ -1,5 +1,15 @@ + mbed TLS ChangeLog (Sorted per branch, date) + ++= mbed TLS 1.3.14 released 2015-10-xx ++ ++Security ++ * Added fix for CVE-2015-xxxxx to prevent heap corruption due to buffer ++ overflow of the hostname or session ticket. (Found by Guido Vranken) ++ ++Changes ++ * Added checking of hostname length in ssl_set_hostname() to ensure domain ++ names are compliant with RFC 1035. ++ + = mbed TLS 1.3.13 reladsed 2015-09-17 + + Security +diff --git a/library/ssl_cli.c b/library/ssl_cli.c +index deeee33..ef86cd2 100644 +--- a/library/ssl_cli.c ++++ b/library/ssl_cli.c +@@ -75,7 +75,7 @@ static void ssl_write_hostname_ext( ssl_context *ssl, + SSL_DEBUG_MSG( 3, ( "client hello, adding server name extension: %s", + ssl->hostname ) ); + +- if( (size_t)(end - p) < ssl->hostname_len + 9 ) ++ if( end < p || (size_t)( end - p ) < ssl->hostname_len + 9 ) + { + SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); + return; +@@ -877,13 +877,13 @@ static int ssl_write_client_hello( ssl_context *ssl ) + ext_len += olen; + #endif + +-#if defined(POLARSSL_SSL_SESSION_TICKETS) +- ssl_write_session_ticket_ext( ssl, p + 2 + ext_len, &olen ); ++#if defined(POLARSSL_SSL_ALPN) ++ ssl_write_alpn_ext( ssl, p + 2 + ext_len, &olen ); + ext_len += olen; + #endif + +-#if defined(POLARSSL_SSL_ALPN) +- ssl_write_alpn_ext( ssl, p + 2 + ext_len, &olen ); ++#if defined(POLARSSL_SSL_SESSION_TICKETS) ++ ssl_write_session_ticket_ext( ssl, p + 2 + ext_len, &olen ); + ext_len += olen; + #endif + diff --git a/debian/patches/vulernable-code-not-present/CVE-2015-5291-4.patch b/debian/patches/vulernable-code-not-present/CVE-2015-5291-4.patch new file mode 100644 index 0000000..2019491 --- /dev/null +++ b/debian/patches/vulernable-code-not-present/CVE-2015-5291-4.patch @@ -0,0 +1,13 @@ +diff --git a/library/ssl_cli.c b/library/ssl_cli.c +index 39dc02e..ef86cd2 100644 +--- a/library/ssl_cli.c ++++ b/library/ssl_cli.c +@@ -133,7 +133,7 @@ static void ssl_write_renegotiation_ext( ssl_context *ssl, + + SSL_DEBUG_MSG( 3, ( "client hello, adding renegotiation extension" ) ); + +- if( end < p || (size_t)(end - p) < 5 + ssl->verify_data_len ) ++ if( (size_t)(end - p) < 5 + ssl->verify_data_len ) + { + SSL_DEBUG_MSG( 1, ( "buffer too small" ) ); + return; diff --git a/debian/tests/build-test b/debian/tests/build-test new file mode 100755 index 0000000..42b7127 --- /dev/null +++ b/debian/tests/build-test @@ -0,0 +1,10 @@ +#!/usr/bin/make -f + +CFLAGS = -O2 -D_FILE_OFFSET_BITS=64 -Wall +LDFLAGS += -lpolarssl + +a.out: programs/hash/hello.c + $(CC) $(CFLAGS) $(OFLAGS) $< $(LDFLAGS) + @echo "Build test of $< succeeded" + ./a.out + @rm -f a.out diff --git a/debian/tests/control b/debian/tests/control new file mode 100644 index 0000000..9b777fd --- /dev/null +++ b/debian/tests/control @@ -0,0 +1,5 @@ +Tests: smoke +Depends: libpolarssl-runtime + +Tests: build-test +Depends: libpolarssl-dev diff --git a/debian/tests/smoke b/debian/tests/smoke new file mode 100755 index 0000000..03df087 --- /dev/null +++ b/debian/tests/smoke @@ -0,0 +1,17 @@ +#!/bin/sh + +set -e + +# Excercise some of the demos +polarssl_hello +polarssl_mpi_demo + +# Make sure output is identical to coreutil versions +[ "$(polarssl_sha1sum /etc/passwd)" = "$(sha1sum /etc/passwd)" ] +[ "$(polarssl_md5sum /etc/passwd)" = "$(md5sum /etc/passwd)" ] + +# Run the selftest +polarssl_selftest + +echo 'Smoke test of polarssl succesful' +exit 0