diff -Nru libotr-3.2.0/debian/changelog libotr-3.2.0/debian/changelog --- libotr-3.2.0/debian/changelog 2014-01-16 02:02:13.000000000 +0000 +++ libotr-3.2.0/debian/changelog 2016-03-10 13:33:45.000000000 +0000 @@ -1,3 +1,12 @@ +libotr (3.2.0-4ubuntu0.3) precise-security; urgency=medium + + * SECURITY UPDATE: memory corruption vulnerability + - debian/patches/CVE-2016-2851.patch: prevent integer overflow in + src/proto.c. + - CVE-2016-2851 + + -- Marc Deslauriers Thu, 10 Mar 2016 08:31:43 -0500 + libotr (3.2.0-4ubuntu0.2) precise-security; urgency=low * SECURITY UPDATE: disable insecure OTRv1 protocol to prevent downgrade diff -Nru libotr-3.2.0/debian/patches/CVE-2016-2851.patch libotr-3.2.0/debian/patches/CVE-2016-2851.patch --- libotr-3.2.0/debian/patches/CVE-2016-2851.patch 1970-01-01 00:00:00.000000000 +0000 +++ libotr-3.2.0/debian/patches/CVE-2016-2851.patch 2016-03-10 13:31:38.000000000 +0000 @@ -0,0 +1,74 @@ +commit ecfd4f468690af6e66b5bf92315972b86071ac1c +Author: Ian Goldberg +Date: Thu Mar 3 13:32:41 2016 +0100 + + Prevent integer overflow on 64-bit architectures when receiving 4GB messages + + In several places in proto.c, the sizes of portions of incoming messages + were stored in variables of type int or unsigned int instead of size_t. + If a message arrives with very large sizes (for example unsigned int + datalen = UINT_MAX), then constructions like malloc(datalen+1) will turn + into malloc(0), which on some architectures returns a non-NULL pointer, + but UINT_MAX bytes will get written to that pointer. + + Ensure all calls to malloc or realloc cannot integer overflow like this. + + Thanks to Markus Vervier of X41 D-Sec GmbH + for the report. + + Signed-off-by: Ian Goldberg + Signed-off-by: David Goulet + +[carnil: Backport to 3.2.1, adjusted for context] +--- a/src/proto.c ++++ b/src/proto.c +@@ -589,7 +589,7 @@ gcry_error_t otrl_proto_accept_data(char + unsigned int sender_keyid, recipient_keyid; + gcry_mpi_t sender_next_y = NULL; + unsigned char ctr[8]; +- unsigned int datalen, reveallen; ++ size_t datalen, reveallen; + unsigned char *data = NULL; + unsigned char *nul = NULL; + unsigned char givenmac[20]; +@@ -769,7 +769,7 @@ OtrlFragmentResult otrl_proto_fragment_a + sscanf(tag, "?OTR,%hu,%hu,%n%*[^,],%n", &k, &n, &start, &end); + if (k > 0 && n > 0 && k <= n && start > 0 && end > 0 && start < end) { + if (k == 1) { +- int fraglen = end - start - 1; ++ size_t fraglen = end - start - 1; + free(context->fragment); + context->fragment = malloc(fraglen + 1); + if (fraglen + 1 > fraglen && context->fragment) { +@@ -787,7 +787,7 @@ OtrlFragmentResult otrl_proto_fragment_a + } + } else if (n == context->fragment_n && + k == context->fragment_k + 1) { +- int fraglen = end - start - 1; ++ size_t fraglen = end - start - 1; + char *newfrag = realloc(context->fragment, + context->fragment_len + fraglen + 1); + if (context->fragment_len + fraglen + 1 > fraglen && newfrag) { +@@ -841,10 +841,10 @@ gcry_error_t otrl_proto_fragment_create( + char ***fragments, const char *message) + { + char *fragdata; +- int fragdatalen = 0; ++ size_t fragdatalen = 0; + unsigned short curfrag = 0; +- int index = 0; +- int msglen = strlen(message); ++ size_t index = 0; ++ size_t msglen = strlen(message); + int headerlen = 19; /* Should vary by number of msgs */ + + char **fragmentarray = malloc(fragment_count * sizeof(char*)); +@@ -857,7 +857,7 @@ gcry_error_t otrl_proto_fragment_create( + int i; + char *fragmentmsg; + +- if (msglen - index < mms - headerlen) { ++ if (msglen - index < (size_t)(mms - headerlen)) { + fragdatalen = msglen - index; + } else { + fragdatalen = mms - headerlen; diff -Nru libotr-3.2.0/debian/patches/series libotr-3.2.0/debian/patches/series --- libotr-3.2.0/debian/patches/series 2014-01-16 02:02:13.000000000 +0000 +++ libotr-3.2.0/debian/patches/series 2016-03-10 13:31:38.000000000 +0000 @@ -2,3 +2,4 @@ 0002-More-thorough-base64-fix.patch 0003-One-more-otrl_base64_decode-in-the-toolkit.patch disable_otr_v1.patch +CVE-2016-2851.patch