diff -Nru openvpn-2.3.10/debian/changelog openvpn-2.3.10/debian/changelog --- openvpn-2.3.10/debian/changelog 2016-02-02 12:34:14.000000000 +0000 +++ openvpn-2.3.10/debian/changelog 2017-06-22 14:32:09.000000000 +0000 @@ -1,3 +1,44 @@ +openvpn (2.3.10-1ubuntu2.1) xenial-security; urgency=medium + + * SECURITY UPDATE: birthday attack when using 64-bit block cipher + - debian/patches/CVE-2016-6329.patch: print warning if 64-bit cipher is + selected in src/openvpn/crypto.c, src/openvpn/crypto_openssl.c, + src/openvpn/crypto_polarssl.c, tests/t_lpback.sh. + - CVE-2016-6329 + * SECURITY UPDATE: DoS due to Exhaustion of Packet-ID counter + - debian/patches/CVE-2017-7479-pre.patch: merge + packet_id_alloc_outgoing() into packet_id_write() in + src/openvpn/crypto.c, src/openvpn/packet_id.c, + src/openvpn/packet_id.h. + - debian/patches/CVE-2017-7479.patch: drop packets instead of assert + out if packet id rolls over in src/openvpn/crypto.c, + src/openvpn/packet_id.c, src/openvpn/packet_id.h. + - CVE-2017-7479 + * SECURITY UPDATE: Remotely-triggerable ASSERT() on malformed IPv6 packet + - debian/patches/CVE-2017-7508.patch: remove assert in + src/openvpn/mss.c. + - CVE-2017-7508 + * SECURITY UPDATE: Remote-triggerable memory leaks + - debian/patches/CVE-2017-7512.patch: fix leaks in + src/openvpn/ssl_verify_openssl.c. + - CVE-2017-7512 + * SECURITY UPDATE: Pre-authentication remote crash/information disclosure + for clients + - debian/patches/CVE-2017-7520.patch: prevent two kinds of stack buffer + OOB reads and a crash for invalid input data in src/openvpn/ntlm.c. + - CVE-2017-7520 + * SECURITY UPDATE: Potential double-free in --x509-alt-username and + memory leaks + - debian/patches/CVE-2017-7521.patch: fix double-free in + src/openvpn/ssl_verify_openssl.c. + - CVE-2017-7521 + * SECURITY UPDATE: DoS in establish_http_proxy_passthru() + - debian/patches/establish_http_proxy_passthru_dos.patch: fix + null-pointer dereference in src/openvpn/proxy.c. + - No CVE number + + -- Marc Deslauriers Thu, 22 Jun 2017 10:32:09 -0400 + openvpn (2.3.10-1ubuntu2) xenial; urgency=medium * debian/openvpn@.service: Add --script-security similar to what got added diff -Nru openvpn-2.3.10/debian/patches/CVE-2016-6329.patch openvpn-2.3.10/debian/patches/CVE-2016-6329.patch --- openvpn-2.3.10/debian/patches/CVE-2016-6329.patch 1970-01-01 00:00:00.000000000 +0000 +++ openvpn-2.3.10/debian/patches/CVE-2016-6329.patch 2017-06-22 14:31:32.000000000 +0000 @@ -0,0 +1,275 @@ +From 610fdbbdb0abf65c1e7620143afccd62cd162a8f Mon Sep 17 00:00:00 2001 +From: Steffan Karger +Date: Tue, 16 Aug 2016 16:46:01 +0200 +Subject: [PATCH] Discourage using 64-bit block ciphers + +As discussed with the development team, we should start moving away from +ciphers with a small block size. For OpenVPN in particular this means +moving away from 64-bit block ciphers, towards 128-bit block ciphers. +This patch makes a start with that by moving ciphers with a block +size < 128 bits to the bottom of the --show-ciphers output, and printing +a warning in the connection phase if such a cipher is used. + +While touching this function, improve the output of --show-ciphers by +ordering the output alphabetically, and changing the output format +slightly. + +[DS: Fixed C89 issues in patch, moving 'int nid' and 'size_t i' declaration + to begining of function instead of in the for-loops. This is also + required to not break building on stricter compiler setups where C99 + must be enabled explicitly ] + +Signed-off-by: Steffan Karger +Acked-by: Arne Schwabe +Message-Id: <1471358761-8828-1-git-send-email-steffan@karger.me> +URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg00030.html +CVE: 2016-6329 +Signed-off-by: David Sommerseth +--- + src/openvpn/crypto.c | 11 +++-- + src/openvpn/crypto_openssl.c | 110 ++++++++++++++++++++++++++++++++++-------- + src/openvpn/crypto_polarssl.c | 41 ++++++++++++++-- + tests/t_lpback.sh | 2 +- + 4 files changed, 135 insertions(+), 29 deletions(-) + +Index: openvpn-2.3.10/src/openvpn/crypto.c +=================================================================== +--- openvpn-2.3.10.orig/src/openvpn/crypto.c 2017-06-22 10:31:29.701291709 -0400 ++++ openvpn-2.3.10/src/openvpn/crypto.c 2017-06-22 10:31:29.693291625 -0400 +@@ -492,9 +492,14 @@ init_key_ctx (struct key_ctx *ctx, struc + dmsg (D_SHOW_KEYS, "%s: CIPHER KEY: %s", prefix, + format_hex (key->cipher, kt->cipher_length, 0, &gc)); + dmsg (D_CRYPTO_DEBUG, "%s: CIPHER block_size=%d iv_size=%d", +- prefix, +- cipher_kt_block_size(kt->cipher), +- cipher_kt_iv_size(kt->cipher)); ++ prefix, cipher_kt_block_size(kt->cipher), ++ cipher_kt_iv_size(kt->cipher)); ++ if (cipher_kt_block_size(kt->cipher) < 128/8) ++ { ++ msg (M_WARN, "WARNING: this cipher's block size is less than 128 bit " ++ "(%d bit). Consider using a --cipher with a larger block size.", ++ cipher_kt_block_size(kt->cipher)*8); ++ } + } + if (kt->digest && kt->hmac_length > 0) + { +Index: openvpn-2.3.10/src/openvpn/crypto_openssl.c +=================================================================== +--- openvpn-2.3.10.orig/src/openvpn/crypto_openssl.c 2017-06-22 10:31:29.701291709 -0400 ++++ openvpn-2.3.10/src/openvpn/crypto_openssl.c 2017-06-22 10:31:29.697291667 -0400 +@@ -278,11 +278,45 @@ translate_cipher_name_to_openvpn (const + return cipher_name; + } + ++static int ++cipher_name_cmp(const void *a, const void *b) ++{ ++ const EVP_CIPHER * const *cipher_a = a; ++ const EVP_CIPHER * const *cipher_b = b; ++ ++ const char *cipher_name_a = ++ translate_cipher_name_to_openvpn(EVP_CIPHER_name(*cipher_a)); ++ const char *cipher_name_b = ++ translate_cipher_name_to_openvpn(EVP_CIPHER_name(*cipher_b)); ++ ++ return strcmp(cipher_name_a, cipher_name_b); ++} ++ ++static void ++print_cipher(const EVP_CIPHER *cipher) ++{ ++ const char *var_key_size = ++ (EVP_CIPHER_flags (cipher) & EVP_CIPH_VARIABLE_LENGTH) ? ++ " by default" : ""; ++ const char *ssl_only = cipher_kt_mode_cbc(cipher) ? ++ "" : ", TLS client/server mode only"; ++ ++ printf ("%s (%d bit key%s, %d bit block%s)\n", ++ translate_cipher_name_to_openvpn (EVP_CIPHER_name (cipher)), ++ EVP_CIPHER_key_length (cipher) * 8, var_key_size, ++ cipher_kt_block_size (cipher) * 8, ssl_only); ++} ++ + void + show_available_ciphers () + { + int nid; ++ size_t i; + ++ /* If we ever exceed this, we must be more selective */ ++ const size_t cipher_list_len = 1000; ++ const EVP_CIPHER *cipher_list[cipher_list_len]; ++ size_t num_ciphers = 0; + #ifndef ENABLE_SMALL + printf ("The following ciphers and cipher modes are available\n" + "for use with " PACKAGE_NAME ". Each cipher shown below may be\n" +@@ -292,29 +326,37 @@ show_available_ciphers () + "is recommended. In static key mode only CBC mode is allowed.\n\n"); + #endif + +- for (nid = 0; nid < 10000; ++nid) /* is there a better way to get the size of the nid list? */ ++ for (nid = 0; nid < 10000; ++nid) + { +- const EVP_CIPHER *cipher = EVP_get_cipherbynid (nid); +- if (cipher) +- { +- if (cipher_kt_mode_cbc(cipher) ++ const EVP_CIPHER *cipher = EVP_get_cipherbynid(nid); ++ if (cipher && (cipher_kt_mode_cbc(cipher) + #ifdef ENABLE_OFB_CFB_MODE + || cipher_kt_mode_ofb_cfb(cipher) + #endif +- ) +- { +- const char *var_key_size = +- (EVP_CIPHER_flags (cipher) & EVP_CIPH_VARIABLE_LENGTH) ? +- "variable" : "fixed"; +- const char *ssl_only = cipher_kt_mode_ofb_cfb(cipher) ? +- " (TLS client/server mode)" : ""; +- +- printf ("%s %d bit default key (%s)%s\n", OBJ_nid2sn (nid), +- EVP_CIPHER_key_length (cipher) * 8, var_key_size, +- ssl_only); +- } ++ )) ++ { ++ cipher_list[num_ciphers++] = cipher; ++ } ++ if (num_ciphers == cipher_list_len) ++ { ++ msg (M_WARN, "WARNING: Too many ciphers, not showing all"); ++ break; + } + } ++ ++ qsort (cipher_list, num_ciphers, sizeof(*cipher_list), cipher_name_cmp); ++ ++ for (i = 0; i < num_ciphers; i++) { ++ if (cipher_kt_block_size(cipher_list[i]) >= 128/8) ++ print_cipher(cipher_list[i]); ++ } ++ ++ printf ("\nThe following ciphers have a block size of less than 128 bits, \n" ++ "and are therefore deprecated. Do not use unless you have to.\n\n"); ++ for (i = 0; i < num_ciphers; i++) { ++ if (cipher_kt_block_size(cipher_list[i]) < 128/8) ++ print_cipher(cipher_list[i]); ++ } + printf ("\n"); + } + +@@ -517,9 +559,37 @@ cipher_kt_iv_size (const EVP_CIPHER *cip + } + + int +-cipher_kt_block_size (const EVP_CIPHER *cipher_kt) +-{ +- return EVP_CIPHER_block_size (cipher_kt); ++cipher_kt_block_size (const EVP_CIPHER *cipher) { ++ /* OpenSSL reports OFB/CFB/GCM cipher block sizes as '1 byte'. To work ++ * around that, try to replace the mode with 'CBC' and return the block size ++ * reported for that cipher, if possible. If that doesn't work, just return ++ * the value reported by OpenSSL. ++ */ ++ char *name = NULL; ++ char *mode_str = NULL; ++ const char *orig_name = NULL; ++ const EVP_CIPHER *cbc_cipher = NULL; ++ ++ int block_size = EVP_CIPHER_block_size(cipher); ++ ++ orig_name = cipher_kt_name(cipher); ++ if (!orig_name) ++ goto cleanup; ++ ++ name = string_alloc(translate_cipher_name_to_openvpn(orig_name), NULL); ++ mode_str = strrchr (name, '-'); ++ if (!mode_str || strlen(mode_str) < 4) ++ goto cleanup; ++ ++ strcpy (mode_str, "-CBC"); ++ ++ cbc_cipher = EVP_get_cipherbyname(translate_cipher_name_from_openvpn(name)); ++ if (cbc_cipher) ++ block_size = EVP_CIPHER_block_size(cbc_cipher); ++ ++cleanup: ++ free (name); ++ return block_size; + } + + int +Index: openvpn-2.3.10/src/openvpn/crypto_polarssl.c +=================================================================== +--- openvpn-2.3.10.orig/src/openvpn/crypto_polarssl.c 2017-06-22 10:31:29.701291709 -0400 ++++ openvpn-2.3.10/src/openvpn/crypto_polarssl.c 2017-06-22 10:31:29.697291667 -0400 +@@ -141,6 +141,25 @@ translate_cipher_name_to_openvpn (const + return pair->openvpn_name; + } + ++static void print_cipher(const cipher_kt_t *info) ++{ ++ if (info && (cipher_kt_mode_cbc(info) ++#ifdef HAVE_AEAD_CIPHER_MODES ++ || cipher_kt_mode_aead(info) ++#endif ++ )) ++ { ++ const char *ssl_only = cipher_kt_mode_cbc(info) ? ++ "" : ", TLS client/server mode only"; ++ const char *var_key_size = info->flags & POLARSSL_CIPHER_VARIABLE_KEY_LEN ++ ? " by default" : ""; ++ ++ printf ("%s (%d bit key%s, %d bit block%s)\n", ++ cipher_kt_name(info), cipher_kt_key_size(info) * 8, var_key_size, ++ cipher_kt_block_size(info) * 8, ssl_only); ++ } ++} ++ + void + show_available_ciphers () + { +@@ -157,12 +176,24 @@ show_available_ciphers () + + while (*ciphers != 0) + { +- const cipher_info_t *info = cipher_info_from_type(*ciphers); +- +- if (info && info->mode == POLARSSL_MODE_CBC) +- printf ("%s %d bit default key\n", +- cipher_kt_name(info), cipher_kt_key_size(info) * 8); ++ const cipher_kt_t *info = cipher_info_from_type(*ciphers); ++ if (info && cipher_kt_block_size(info) >= 128/8) ++ { ++ print_cipher(info); ++ } ++ ciphers++; ++ } + ++ printf ("\nThe following ciphers have a block size of less than 128 bits, \n" ++ "and are therefore deprecated. Do not use unless you have to.\n\n"); ++ ciphers = cipher_list(); ++ while (*ciphers != 0) ++ { ++ const cipher_kt_t *info = cipher_info_from_type(*ciphers); ++ if (info && cipher_kt_block_size(info) < 128/8) ++ { ++ print_cipher(info); ++ } + ciphers++; + } + printf ("\n"); +Index: openvpn-2.3.10/tests/t_lpback.sh +=================================================================== +--- openvpn-2.3.10.orig/tests/t_lpback.sh 2017-06-22 10:31:29.701291709 -0400 ++++ openvpn-2.3.10/tests/t_lpback.sh 2017-06-22 10:31:29.697291667 -0400 +@@ -26,7 +26,7 @@ trap "rm -f key.$$ log.$$ ; exit 1" 0 3 + + # Get list of supported ciphers from openvpn --show-ciphers output + CIPHERS=$(${top_builddir}/src/openvpn/openvpn --show-ciphers | \ +- sed -e '1,/^$/d' -e s'/ .*//' -e '/^\s*$/d' | sort) ++ sed -e '/The following/,/^$/d' -e s'/ .*//' -e '/^\s*$/d') + + # SK, 2014-06-04: currently the DES-EDE3-CFB1 implementation of OpenSSL is + # broken (see http://rt.openssl.org/Ticket/Display.html?id=2867), so exclude diff -Nru openvpn-2.3.10/debian/patches/CVE-2017-7479.patch openvpn-2.3.10/debian/patches/CVE-2017-7479.patch --- openvpn-2.3.10/debian/patches/CVE-2017-7479.patch 1970-01-01 00:00:00.000000000 +0000 +++ openvpn-2.3.10/debian/patches/CVE-2017-7479.patch 2017-06-22 14:31:42.000000000 +0000 @@ -0,0 +1,163 @@ +Backport of: + +From b727643cdf4e078f132a90e1c474a879a5760578 Mon Sep 17 00:00:00 2001 +From: Steffan Karger +Date: Tue, 9 May 2017 21:30:07 +0200 +Subject: [PATCH] Drop packets instead of assert out if packet id rolls over + (CVE-2017-7479) + +Previously, if a mode was selected where packet ids are not allowed to roll +over, but renegotiation does not succeed for some reason (e.g. no password +entered in time, certificate expired or a malicious peer that refuses the +renegotiaion on purpose) we would continue to use the old keys. Until the +packet ID would roll over and we would ASSERT() out. + +Given that this can be triggered on purpose by an authenticated peer, this +is a fix for an authenticated remote DoS vulnerability. An attack is +rather inefficient though; a peer would need to get us to send 2^32 +packets (min-size packet is IP+UDP+OPCODE+PID+TAG (no payload), results in +(20+8+1+4+16)*2^32 bytes, or approx. 196 GB). + +This is a fix for finding 5.2 from the OSTIF / Quarkslab audit. + +CVE: 2017-7479 +Signed-off-by: Steffan Karger +Acked-by: Gert Doering +Acked-by: David Sommerseth +Message-Id: <1494358209-4568-1-git-send-email-steffan.karger@fox-it.com> +URL: http://www.mail-archive.com/search?l=mid&q=1494358209-4568-1-git-send-email-steffan.karger@fox-it.com +Signed-off-by: David Sommerseth +--- + Changes.rst | 10 ++++++++++ + src/openvpn/crypto.c | 18 +++++++++++++----- + src/openvpn/packet_id.c | 22 ++++++++++++++++------ + src/openvpn/packet_id.h | 1 + + tests/unit_tests/openvpn/test_packet_id.c | 11 +++++++++-- + 5 files changed, 49 insertions(+), 13 deletions(-) + +#diff --git a/Changes.rst b/Changes.rst +#index 1c0154c46..183e9fa4a 100644 +#--- a/Changes.rst +#+++ b/Changes.rst +#@@ -104,6 +104,16 @@ Behavioral changes +# +# - Do not randomize resolving of IP addresses in getaddr() +# +#+Version 2.3.15 +#+============== +#+ +#+Security fixes +#+-------------- +#+- Fix an authenticated remote DoS vulnerability that could be triggered by +#+ causing a packet id roll over. An attack is rather inefficient; a peer +#+ would need to get us to send at least about 196 GB of data. +#+ (OSTIF/Quarkslab audit finding 5.2, CVE-2017-7479) +#+ +# Version 2.3.14 +# ============== +# +Index: openvpn-2.3.11/src/openvpn/crypto.c +=================================================================== +--- openvpn-2.3.11.orig/src/openvpn/crypto.c 2017-06-22 09:03:24.309316314 -0400 ++++ openvpn-2.3.11/src/openvpn/crypto.c 2017-06-22 09:03:24.305316271 -0400 +@@ -112,9 +112,11 @@ openvpn_encrypt (struct buffer *buf, str + prng_bytes (iv_buf, iv_size); + + /* Put packet ID in plaintext buffer or IV, depending on cipher mode */ +- if (opt->packet_id) ++ if (opt->packet_id ++ && !packet_id_write (&opt->packet_id->send, buf, BOOL_CAST (opt->flags & CO_PACKET_ID_LONG_FORM), true)) + { +- ASSERT (packet_id_write (&opt->packet_id->send, buf, BOOL_CAST (opt->flags & CO_PACKET_ID_LONG_FORM), true)); ++ msg (D_CRYPT_ERRORS, "ENCRYPT ERROR: packet ID roll over"); ++ goto err; + } + } + else if (cipher_kt_mode_ofb_cfb(cipher_kt)) +@@ -126,7 +128,11 @@ openvpn_encrypt (struct buffer *buf, str + + memset (iv_buf, 0, iv_size); + buf_set_write (&b, iv_buf, iv_size); +- ASSERT (packet_id_write (&opt->packet_id->send, &b, true, false)); ++ if (!packet_id_write (&opt->packet_id->send, &b, true, false)) ++ { ++ msg (D_CRYPT_ERRORS, "ENCRYPT ERROR: packet ID roll over"); ++ goto err; ++ } + } + else /* We only support CBC, CFB, or OFB modes right now */ + { +@@ -185,9 +191,11 @@ openvpn_encrypt (struct buffer *buf, str + } + else /* No Encryption */ + { +- if (opt->packet_id) ++ if (opt->packet_id ++ && !packet_id_write (&opt->packet_id->send, buf, BOOL_CAST (opt->flags & CO_PACKET_ID_LONG_FORM), true)) + { +- ASSERT (packet_id_write (&opt->packet_id->send, buf, BOOL_CAST (opt->flags & CO_PACKET_ID_LONG_FORM), true)); ++ msg (D_CRYPT_ERRORS, "ENCRYPT ERROR: packet ID roll over"); ++ goto err; + } + work = *buf; + } +Index: openvpn-2.3.11/src/openvpn/packet_id.c +=================================================================== +--- openvpn-2.3.11.orig/src/openvpn/packet_id.c 2017-06-22 09:03:24.309316314 -0400 ++++ openvpn-2.3.11/src/openvpn/packet_id.c 2017-06-22 09:03:24.305316271 -0400 +@@ -294,27 +294,37 @@ packet_id_read (struct packet_id_net *pi + return true; + } + +-static void ++static bool + packet_id_send_update(struct packet_id_send *p, bool long_form) + { + if (!p->time) + { + p->time = now; + } +- p->id++; +- if (!p->id) ++ if (p->id == PACKET_ID_MAX) + { +- ASSERT(long_form); ++ /* Packet ID only allowed to roll over if using long form and time has ++ * moved forward since last roll over. ++ */ ++ if (!long_form || now <= p->time) ++ { ++ return false; ++ } + p->time = now; +- p->id = 1; ++ p->id = 0; + } ++ p->id++; ++ return true; + } + + bool + packet_id_write (struct packet_id_send *p, struct buffer *buf, bool long_form, + bool prepend) + { +- packet_id_send_update(p, long_form); ++ if (!packet_id_send_update(p, long_form)) ++ { ++ return false; ++ } + + const packet_id_type net_id = htonpid(p->id); + const net_time_t net_time = htontime(p->time); +Index: openvpn-2.3.11/src/openvpn/packet_id.h +=================================================================== +--- openvpn-2.3.11.orig/src/openvpn/packet_id.h 2017-06-22 09:03:24.309316314 -0400 ++++ openvpn-2.3.11/src/openvpn/packet_id.h 2017-06-22 09:03:24.305316271 -0400 +@@ -50,6 +50,7 @@ + * to for network transmission. + */ + typedef uint32_t packet_id_type; ++#define PACKET_ID_MAX UINT32_MAX + typedef uint32_t net_time_t; + + /* diff -Nru openvpn-2.3.10/debian/patches/CVE-2017-7479-pre.patch openvpn-2.3.10/debian/patches/CVE-2017-7479-pre.patch --- openvpn-2.3.10/debian/patches/CVE-2017-7479-pre.patch 1970-01-01 00:00:00.000000000 +0000 +++ openvpn-2.3.10/debian/patches/CVE-2017-7479-pre.patch 2017-06-22 14:31:37.000000000 +0000 @@ -0,0 +1,170 @@ +Backport of: + +From 5d747770efa0611cc6cfeb6b3a5853bf51046d53 Mon Sep 17 00:00:00 2001 +From: Steffan Karger +Date: Tue, 9 May 2017 21:10:36 +0200 +Subject: [PATCH] cleanup: merge packet_id_alloc_outgoing() into + packet_id_write() + +The functions packet_id_alloc_outgoing() and packet_id_write() were +always called in tandem. Instead of forcing the caller to allocate a +packet_id_net to do so, merge the two functions. This simplifies the API +and reduces the chance on mistakes in the future. + +This patch adds unit tests to verify the behaviour of packet_id_write(). +Verifying that we assert out correctly required the change to mock_msg.c. + +This patch was cherry-picked from a87e1431 (master). + +Signed-off-by: Steffan Karger +Acked-by: David Sommerseth +Message-Id: <1494357036-3529-1-git-send-email-steffan.karger@fox-it.com> +URL: http://www.mail-archive.com/search?l=mid&q=1494357036-3529-1-git-send-email-steffan.karger@fox-it.com +Signed-off-by: David Sommerseth +--- + configure.ac | 1 + + src/openvpn/crypto.c | 12 +-- + src/openvpn/packet_id.c | 24 ++++- + src/openvpn/packet_id.h | 34 +++--- + tests/unit_tests/Makefile.am | 2 +- + tests/unit_tests/openvpn/Makefile.am | 24 +++++ + tests/unit_tests/openvpn/mock_msg.c | 98 +++++++++++++++++ + tests/unit_tests/openvpn/mock_msg.h | 35 +++++++ + tests/unit_tests/openvpn/test_packet_id.c | 169 ++++++++++++++++++++++++++++++ + 9 files changed, 365 insertions(+), 34 deletions(-) + create mode 100644 tests/unit_tests/openvpn/Makefile.am + create mode 100644 tests/unit_tests/openvpn/mock_msg.c + create mode 100644 tests/unit_tests/openvpn/mock_msg.h + create mode 100644 tests/unit_tests/openvpn/test_packet_id.c + +diff --git a/src/openvpn/crypto.c b/src/openvpn/crypto.c +index e9d6f03f7..f153367e6 100644 +--- a/src/openvpn/crypto.c ++++ b/src/openvpn/crypto.c +@@ -114,23 +114,19 @@ openvpn_encrypt (struct buffer *buf, struct buffer work, + /* Put packet ID in plaintext buffer or IV, depending on cipher mode */ + if (opt->packet_id) + { +- struct packet_id_net pin; +- packet_id_alloc_outgoing (&opt->packet_id->send, &pin, BOOL_CAST (opt->flags & CO_PACKET_ID_LONG_FORM)); +- ASSERT (packet_id_write (&pin, buf, BOOL_CAST (opt->flags & CO_PACKET_ID_LONG_FORM), true)); ++ ASSERT (packet_id_write (&opt->packet_id->send, buf, BOOL_CAST (opt->flags & CO_PACKET_ID_LONG_FORM), true)); + } + } + else if (cipher_kt_mode_ofb_cfb(cipher_kt)) + { +- struct packet_id_net pin; + struct buffer b; + + ASSERT (opt->flags & CO_USE_IV); /* IV and packet-ID required */ + ASSERT (opt->packet_id); /* for this mode. */ + +- packet_id_alloc_outgoing (&opt->packet_id->send, &pin, true); + memset (iv_buf, 0, iv_size); + buf_set_write (&b, iv_buf, iv_size); +- ASSERT (packet_id_write (&pin, &b, true, false)); ++ ASSERT (packet_id_write (&opt->packet_id->send, &b, true, false)); + } + else /* We only support CBC, CFB, or OFB modes right now */ + { +@@ -191,9 +187,7 @@ openvpn_encrypt (struct buffer *buf, struct buffer work, + { + if (opt->packet_id) + { +- struct packet_id_net pin; +- packet_id_alloc_outgoing (&opt->packet_id->send, &pin, BOOL_CAST (opt->flags & CO_PACKET_ID_LONG_FORM)); +- ASSERT (packet_id_write (&pin, buf, BOOL_CAST (opt->flags & CO_PACKET_ID_LONG_FORM), true)); ++ ASSERT (packet_id_write (&opt->packet_id->send, buf, BOOL_CAST (opt->flags & CO_PACKET_ID_LONG_FORM), true)); + } + work = *buf; + } +diff --git a/src/openvpn/packet_id.c b/src/openvpn/packet_id.c +index a690bbcf3..c637be66d 100644 +--- a/src/openvpn/packet_id.c ++++ b/src/openvpn/packet_id.c +@@ -294,12 +294,30 @@ packet_id_read (struct packet_id_net *pin, struct buffer *buf, bool long_form) + return true; + } + ++static void ++packet_id_send_update(struct packet_id_send *p, bool long_form) ++{ ++ if (!p->time) ++ { ++ p->time = now; ++ } ++ p->id++; ++ if (!p->id) ++ { ++ ASSERT(long_form); ++ p->time = now; ++ p->id = 1; ++ } ++} ++ + bool +-packet_id_write (const struct packet_id_net *pin, struct buffer *buf, bool long_form, bool prepend) ++packet_id_write (struct packet_id_send *p, struct buffer *buf, bool long_form, ++ bool prepend) + { +- packet_id_type net_id = htonpid (pin->id); +- net_time_t net_time = htontime (pin->time); ++ packet_id_send_update(p, long_form); + ++ const packet_id_type net_id = htonpid(p->id); ++ const net_time_t net_time = htontime(p->time); + if (prepend) + { + if (long_form) +diff --git a/src/openvpn/packet_id.h b/src/openvpn/packet_id.h +index b02d6fc23..f6fa9bd1e 100644 +--- a/src/openvpn/packet_id.h ++++ b/src/openvpn/packet_id.h +@@ -252,7 +252,19 @@ const char *packet_id_persist_print (const struct packet_id_persist *p, struct g + */ + + bool packet_id_read (struct packet_id_net *pin, struct buffer *buf, bool long_form); +-bool packet_id_write (const struct packet_id_net *pin, struct buffer *buf, bool long_form, bool prepend); ++ ++/** ++ * Write a packet ID to buf, and update the packet ID state. ++ * ++ * @param p Packet ID state. ++ * @param buf Buffer to write the packet ID too ++ * @param long_form If true, also update and write time_t to buf ++ * @param prepend If true, prepend to buffer, otherwise apppend. ++ * ++ * @return true if successful, false otherwise. ++ */ ++bool packet_id_write (struct packet_id_send *p, struct buffer *buf, ++ bool long_form, bool prepend); + + /* + * Inline functions. +@@ -294,26 +306,6 @@ packet_id_close_to_wrapping (const struct packet_id_send *p) + return p->id >= PACKET_ID_WRAP_TRIGGER; + } + +-/* +- * Allocate an outgoing packet id. +- * Sequence number ranges from 1 to 2^32-1. +- * In long_form, a time_t is added as well. +- */ +-static inline void +-packet_id_alloc_outgoing (struct packet_id_send *p, struct packet_id_net *pin, bool long_form) +-{ +- if (!p->time) +- p->time = now; +- pin->id = ++p->id; +- if (!pin->id) +- { +- ASSERT (long_form); +- p->time = now; +- pin->id = p->id = 1; +- } +- pin->time = p->time; +-} +- + static inline bool + check_timestamp_delta (time_t remote, unsigned int max_delta) + { diff -Nru openvpn-2.3.10/debian/patches/CVE-2017-7508.patch openvpn-2.3.10/debian/patches/CVE-2017-7508.patch --- openvpn-2.3.10/debian/patches/CVE-2017-7508.patch 1970-01-01 00:00:00.000000000 +0000 +++ openvpn-2.3.10/debian/patches/CVE-2017-7508.patch 2017-06-22 14:31:48.000000000 +0000 @@ -0,0 +1,59 @@ +From fc61d1bda112ffc669dbde961fab19f60b3c7439 Mon Sep 17 00:00:00 2001 +From: Gert Doering +Date: Tue, 13 Jun 2017 22:08:32 +0200 +Subject: [PATCH] Fix remotely-triggerable ASSERT() on malformed IPv6 packet. + +Correct sanity checks on IPv6 packet length in mss_fixup_ipv6(), +and change the ASSERT() check in mss_fixup_dowork() into a simple +"return" (= the TCP header will simply not be inspected further). + +CVE-2017-7508 has been assigned due to the serious nature of the +bug: it can be used to remotely shutdown an openvpn server or +client, if IPv6 and --mssfix are enabled and the IPv6 networks used +inside the VPN are known. + +Found by Guido Vranken . + +v2: style changes + +CVE: 2017-7508 +Signed-off-by: Gert Doering +Acked-by: Steffan Karger +Message-Id: <20170613200832.15027-1-gert@greenie.muc.de> +URL: https://www.mail-archive.com/search?l=mid&q=20170613200832.15027-1-gert@greenie.muc.de +Signed-off-by: Gert Doering +(cherry picked from commit c3f47077a7756de5929094569421a95aa66f2022) +--- + src/openvpn/mss.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +diff --git a/src/openvpn/mss.c b/src/openvpn/mss.c +index f930942a2..c91751d14 100644 +--- a/src/openvpn/mss.c ++++ b/src/openvpn/mss.c +@@ -110,8 +110,12 @@ mss_fixup_ipv6 (struct buffer *buf, int maxmss) + if ( pip6->nexthdr != OPENVPN_IPPROTO_TCP ) + return; + ++ /* skip IPv6 header (40 bytes), ++ * verify remainder is large enough to contain a full TCP header ++ */ + newbuf = *buf; +- if ( buf_advance( &newbuf, 40 ) ) ++ if (buf_advance( &newbuf, 40 ) ++ && BLEN(&newbuf) >= (int) sizeof(struct openvpn_tcphdr)) + { + struct openvpn_tcphdr *tc = (struct openvpn_tcphdr *) BPTR (&newbuf); + if (tc->flags & OPENVPN_TCPH_SYN_MASK) +@@ -133,7 +137,10 @@ mss_fixup_dowork (struct buffer *buf, uint16_t maxmss) + int accumulate; + struct openvpn_tcphdr *tc; + +- ASSERT (BLEN (buf) >= (int) sizeof (struct openvpn_tcphdr)); ++ if (BLEN(buf) < (int) sizeof(struct openvpn_tcphdr)) ++ { ++ return; ++ } + + verify_align_4 (buf); + tc = (struct openvpn_tcphdr *) BPTR (buf); diff -Nru openvpn-2.3.10/debian/patches/CVE-2017-7512.patch openvpn-2.3.10/debian/patches/CVE-2017-7512.patch --- openvpn-2.3.10/debian/patches/CVE-2017-7512.patch 1970-01-01 00:00:00.000000000 +0000 +++ openvpn-2.3.10/debian/patches/CVE-2017-7512.patch 2017-06-22 14:31:53.000000000 +0000 @@ -0,0 +1,76 @@ +From 84e1775961de1c9d2ab32159fc03f758591f5238 Mon Sep 17 00:00:00 2001 +From: Steffan Karger +Date: Mon, 19 Jun 2017 11:28:38 +0200 +Subject: [PATCH] Fix remote-triggerable memory leaks (CVE-2017-7521) + +Several of our OpenSSL-specific certificate-parsing code paths did not +always clear all allocated memory. Since a client can cause a few bytes +of memory to be leaked for each connection attempt, a client can cause a +server to run out of memory and thereby kill the server. That makes this +a (quite inefficient) DoS attack. + +When using the --x509-alt-username option on openssl builds with an +extension (argument prefixed with "ext:", e.g. "ext:subjectAltName"), the +code would not free all allocated memory. Fix this by using the proper +free function. + +If ASN1_STRING_to_UTF8() returns 0, it didn't fail and *did* allocate +memory. So also free the returned buffer if it returns 0. + +These issues were found, analysed and reported to the OpenVPN team by Guido +Vranken. + +CVE: 2017-7521 +Signed-off-by: Steffan Karger +Acked-by: Gert Doering +Acked-by: David Sommerseth +Acked-by: Guido Vranken +Message-Id: <1497864520-12219-4-git-send-email-steffan.karger@fox-it.com> +URL: https://www.mail-archive.com/search?l=mid&q=1497864520-12219-4-git-send-email-steffan.karger@fox-it.com +Signed-off-by: Gert Doering +(cherry picked from commit 2d032c7fcdfd692c851ea2fa858b4c2d9ea7d52d) +--- + src/openvpn/ssl_verify_openssl.c | 9 ++++----- + 1 file changed, 4 insertions(+), 5 deletions(-) + +diff --git a/src/openvpn/ssl_verify_openssl.c b/src/openvpn/ssl_verify_openssl.c +index d64f83c91..11eb7be51 100644 +--- a/src/openvpn/ssl_verify_openssl.c ++++ b/src/openvpn/ssl_verify_openssl.c +@@ -139,7 +139,7 @@ bool extract_x509_extension(X509 *cert, char *fieldname, char *out, int size) + break; + } + } +- sk_GENERAL_NAME_free (extensions); ++ GENERAL_NAMES_free(extensions); + } + return retval; + } +@@ -186,8 +186,7 @@ extract_x509_field_ssl (X509_NAME *x509, const char *field_name, char *out, + asn1 = X509_NAME_ENTRY_get_data(x509ne); + if (!asn1) + return FAILURE; +- tmp = ASN1_STRING_to_UTF8(&buf, asn1); +- if (tmp <= 0) ++ if (ASN1_STRING_to_UTF8(&buf, asn1) < 0) + return FAILURE; + + strncpynt(out, (char *)buf, size); +@@ -359,7 +358,7 @@ x509_setenv_track (const struct x509_track *xt, struct env_set *es, const int de + ASN1_STRING *val = X509_NAME_ENTRY_get_data (ent); + unsigned char *buf; + buf = (unsigned char *)1; /* bug in OpenSSL 0.9.6b ASN1_STRING_to_UTF8 requires this workaround */ +- if (ASN1_STRING_to_UTF8 (&buf, val) > 0) ++ if (ASN1_STRING_to_UTF8 (&buf, val) >= 0) + { + do_setenv_x509(es, xt->name, (char *)buf, depth); + OPENSSL_free (buf); +@@ -435,7 +434,7 @@ x509_setenv (struct env_set *es, int cert_depth, openvpn_x509_cert_t *peer_cert) + if (!objbuf) + continue; + buf = (unsigned char *)1; /* bug in OpenSSL 0.9.6b ASN1_STRING_to_UTF8 requires this workaround */ +- if (ASN1_STRING_to_UTF8 (&buf, val) <= 0) ++ if (ASN1_STRING_to_UTF8 (&buf, val) < 0) + continue; + name_expand_size = 64 + strlen (objbuf); + name_expand = (char *) malloc (name_expand_size); diff -Nru openvpn-2.3.10/debian/patches/CVE-2017-7520.patch openvpn-2.3.10/debian/patches/CVE-2017-7520.patch --- openvpn-2.3.10/debian/patches/CVE-2017-7520.patch 1970-01-01 00:00:00.000000000 +0000 +++ openvpn-2.3.10/debian/patches/CVE-2017-7520.patch 2017-06-22 14:31:57.000000000 +0000 @@ -0,0 +1,58 @@ +From f38a4a105979b87ebebe9be1c3d323116d3fb924 Mon Sep 17 00:00:00 2001 +From: Guido Vranken +Date: Fri, 19 May 2017 14:04:25 +0200 +Subject: [PATCH] Prevent two kinds of stack buffer OOB reads and a crash for + invalid input data + +Pre-authentication remote crash/information disclosure for clients + +If clients use a HTTP proxy with NTLM authentication (i.e. +"--http-proxy [|'auto'|'auto-nct'] ntlm2"), +a man-in-the-middle attacker between the client and the proxy can +cause the client to crash or disclose at most 96 bytes of stack +memory. The disclosed stack memory is likely to contain the proxy +password. + +If the proxy password is not reused, this is unlikely to compromise +the security of the OpenVPN tunnel itself. Clients who do not use +the --http-proxy option with ntlm2 authentication are not affected. + +CVE: 2017-7520 +Signed-off-by: Guido Vranken +Acked-by: Gert Doering +Message-Id: +URL: https://www.mail-archive.com/search?l=mid&q=CAO5O-EJvHKid-zTj+hmFG_3Gv78ixqCayE9=C62DZaxN32WNtQ@mail.gmail.com +Signed-off-by: Gert Doering +(cherry picked from commit 7718c8984f04b507c1885f363970e2124e3c6c77) +--- + src/openvpn/ntlm.c | 10 ++++++++-- + 1 file changed, 8 insertions(+), 2 deletions(-) + +Index: openvpn-2.3.11/src/openvpn/ntlm.c +=================================================================== +--- openvpn-2.3.11.orig/src/openvpn/ntlm.c 2017-06-22 09:04:29.486006573 -0400 ++++ openvpn-2.3.11/src/openvpn/ntlm.c 2017-06-22 09:04:29.482006531 -0400 +@@ -193,7 +193,7 @@ ntlm_phase_3 (const struct http_proxy_in + */ + + char pwbuf[sizeof (p->up.password) * 2]; /* for unicode password */ +- char buf2[128]; /* decoded reply from proxy */ ++ unsigned char buf2[128]; /* decoded reply from proxy */ + unsigned char phase3[464]; + + char md4_hash[MD4_DIGEST_LENGTH+5]; +@@ -282,7 +282,13 @@ ntlm_phase_3 (const struct http_proxy_in + tib_len = buf2[0x28];/* Get Target Information block size */ + if (tib_len > 96) tib_len = 96; + { +- char *tib_ptr = buf2 + buf2[0x2c]; /* Get Target Information block pointer */ ++ char *tib_ptr; ++ int tib_pos = buf2[0x2c]; ++ if (tib_pos + tib_len > sizeof(buf2)) ++ { ++ return NULL; ++ } ++ tib_ptr = buf2 + tib_pos; /* Get Target Information block pointer */ + memcpy(&ntlmv2_blob[0x1c], tib_ptr, tib_len); /* Copy Target Information block into the blob */ + } + } else { diff -Nru openvpn-2.3.10/debian/patches/CVE-2017-7521.patch openvpn-2.3.10/debian/patches/CVE-2017-7521.patch --- openvpn-2.3.10/debian/patches/CVE-2017-7521.patch 1970-01-01 00:00:00.000000000 +0000 +++ openvpn-2.3.10/debian/patches/CVE-2017-7521.patch 2017-06-22 14:32:01.000000000 +0000 @@ -0,0 +1,51 @@ +From 1dde0cd6e5e6a0f2f45ec9969b7ff1b6537514ad Mon Sep 17 00:00:00 2001 +From: Steffan Karger +Date: Mon, 19 Jun 2017 11:28:40 +0200 +Subject: [PATCH] Fix potential double-free in --x509-alt-username + (CVE-2017-7521) + +We didn't check the return value of ASN1_STRING_to_UTF8() in +extract_x509_extension(). Ignoring such a failure could result in buf +being free'd twice. An error in ASN1_STRING_to_UTF8() can be caused +remotely if the peer can make the local process run out of memory. + +The problem can only be triggered for configurations that use the +--x509-alt-username option with an x509 extension (i.e. the option +parameter starts with "ext:"). + +This issue was discovered, analysed and reported to the OpenVPN team by +Guido Vranken. + +Extensive testing by Guido Vranken gives confidence that this function +is very unlikely to fail in real-world usage (using subjectAltName or +issuerAltName extensions) for other reasons than memory exhaustion. + +CVE: 2017-7521 +Signed-off-by: Steffan Karger +Acked-by: Gert Doering +Acked-by: David Sommerseth +Acked-by: Guido Vranken +Message-Id: <1497864520-12219-6-git-send-email-steffan.karger@fox-it.com> +URL: https://www.mail-archive.com/search?l=mid&q=1497864520-12219-6-git-send-email-steffan.karger@fox-it.com +Signed-off-by: Gert Doering +(cherry picked from commit cb4e35ece4a5b70b10ef9013be3bff263d82f32b) +--- + src/openvpn/ssl_verify_openssl.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +Index: openvpn-2.3.11/src/openvpn/ssl_verify_openssl.c +=================================================================== +--- openvpn-2.3.11.orig/src/openvpn/ssl_verify_openssl.c 2017-06-22 09:04:36.566081555 -0400 ++++ openvpn-2.3.11/src/openvpn/ssl_verify_openssl.c 2017-06-22 09:04:36.562081513 -0400 +@@ -122,7 +122,10 @@ bool extract_x509_extension(X509 *cert, + switch (name->type) + { + case GEN_EMAIL: +- ASN1_STRING_to_UTF8((unsigned char**)&buf, name->d.ia5); ++ if (ASN1_STRING_to_UTF8((unsigned char **)&buf, name->d.ia5) < 0) ++ { ++ continue; ++ } + if ( strlen (buf) != name->d.ia5->length ) + { + msg (D_TLS_ERRORS, "ASN1 ERROR: string contained terminating zero"); diff -Nru openvpn-2.3.10/debian/patches/establish_http_proxy_passthru_dos.patch openvpn-2.3.10/debian/patches/establish_http_proxy_passthru_dos.patch --- openvpn-2.3.10/debian/patches/establish_http_proxy_passthru_dos.patch 1970-01-01 00:00:00.000000000 +0000 +++ openvpn-2.3.10/debian/patches/establish_http_proxy_passthru_dos.patch 2017-06-22 14:32:06.000000000 +0000 @@ -0,0 +1,38 @@ +From 479b6d13d8c230c11b6315665bf00998a1424eef Mon Sep 17 00:00:00 2001 +From: Guido Vranken +Date: Fri, 16 Jun 2017 02:58:56 +0200 +Subject: [PATCH] Fix a null-pointer dereference in + establish_http_proxy_passthru() + +Prevents that the client crashes if the peer does not specify +the 'realm' and/or 'nonce' values. These pointers are +dereferenced in DigestCalcHA1() and DigestCalcResponse(); +hence, if not set, a null-pointer dereference would occur. + +Signed-off-by: Guido Vranken +Acked-by: Gert Doering +Message-Id: <1497574736-2092-1-git-send-email-gv@guidovranken.nl> +URL: https://www.mail-archive.com/openvpn-devel@lists.sourceforge.net/msg14844.html +Signed-off-by: Gert Doering +(cherry picked from commit 14865773ad64d861128bc80ad44c37bdc307c996) +--- + src/openvpn/proxy.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +Index: openvpn-2.3.11/src/openvpn/proxy.c +=================================================================== +--- openvpn-2.3.11.orig/src/openvpn/proxy.c 2017-06-22 09:04:43.270152555 -0400 ++++ openvpn-2.3.11/src/openvpn/proxy.c 2017-06-22 09:04:43.266152513 -0400 +@@ -724,6 +724,12 @@ establish_http_proxy_passthru (struct ht + const char *algor = get_pa_var("algorithm", pa, &gc); + const char *opaque = get_pa_var("opaque", pa, &gc); + ++ if ( !realm || !nonce ) ++ { ++ msg(D_LINK_ERRORS, "HTTP proxy: digest auth failed, malformed response from server: realm= or nonce= missing" ); ++ goto error; ++ } ++ + /* generate a client nonce */ + ASSERT(rand_bytes(cnonce_raw, sizeof(cnonce_raw))); + cnonce = make_base64_string2(cnonce_raw, sizeof(cnonce_raw), &gc); diff -Nru openvpn-2.3.10/debian/patches/series openvpn-2.3.10/debian/patches/series --- openvpn-2.3.10/debian/patches/series 2016-01-20 11:03:12.000000000 +0000 +++ openvpn-2.3.10/debian/patches/series 2017-06-22 14:32:06.000000000 +0000 @@ -6,3 +6,11 @@ kfreebsd_support.patch accommodate_typo.patch manpage_fixes.patch +CVE-2016-6329.patch +CVE-2017-7479-pre.patch +CVE-2017-7479.patch +CVE-2017-7508.patch +CVE-2017-7512.patch +CVE-2017-7520.patch +CVE-2017-7521.patch +establish_http_proxy_passthru_dos.patch