Package: release.debian.org Severity: normal User: release.debian....@packages.debian.org Usertags: unblock
Please unblock package libotr Fixes security hole (possible buffer overflow in base64 routines): #684121 The only change from 3.2.0-4 (currently in wheezy) and 3.2.1-1 is the security fix, see the attached debdiff. unblock libotr/3.2.1-1 -- System Information: Debian Release: wheezy/sid APT prefers unstable APT policy: (500, 'unstable') Architecture: ia64 Kernel: Linux 2.6.29.2 (SMP w/2 CPU cores) Locale: LANG=C, LC_CTYPE=C (charmap=ANSI_X3.4-1968) Shell: /bin/sh linked to /bin/dash
diff -Nru libotr-3.2.0/ChangeLog libotr-3.2.1/ChangeLog --- libotr-3.2.0/ChangeLog 2008-06-15 22:16:34.000000000 +0200 +++ libotr-3.2.1/ChangeLog 2012-08-07 12:21:35.000000000 +0200 @@ -1,3 +1,20 @@ +2012-07-27 + + * src/version.h: Update libotr version number to 3.2.1 + +2012-07-19 + + * src/b64.[ch], src/proto.c, toolkit/parse.c: Clean up the + previous b64 patch and apply it to all places where + otrl_base64_decode() is called. + +2012-07-17 + + * src/b64.c: Use ceil instead of floor to compute the size + of the data buffer. This prevents a one-byte heap buffer + overflow. Thanks to Justin Ferguson <jnfergu...@gmail.com> + for the report. + 2008-06-15: * README: Release version 3.2.0. diff -Nru libotr-3.2.0/debian/changelog libotr-3.2.1/debian/changelog --- libotr-3.2.0/debian/changelog 2011-12-26 18:34:38.000000000 +0100 +++ libotr-3.2.1/debian/changelog 2012-08-07 12:25:12.000000000 +0200 @@ -1,3 +1,9 @@ +libotr (3.2.1-1) unstable; urgency=high + + * Fix potential buffer overflow in base64 routines (Closes: #684121) + + -- Thibaut VARENE <vare...@debian.org> Tue, 07 Aug 2012 12:24:15 +0200 + libotr (3.2.0-4) unstable; urgency=low * lintian cleanup: diff -Nru libotr-3.2.0/src/b64.c libotr-3.2.1/src/b64.c --- libotr-3.2.0/src/b64.c 2008-05-27 14:35:28.000000000 +0200 +++ libotr-3.2.1/src/b64.c 2012-08-07 12:21:31.000000000 +0200 @@ -55,7 +55,7 @@ \******************************************************************* */ /* system headers */ -#include <stdlib.h> +#include <stdio.h> #include <string.h> /* libotr headers */ @@ -147,8 +147,9 @@ * base64 decode data. Skip non-base64 chars, and terminate at the * first '=', or the end of the buffer. * - * The buffer data must contain at least (base64len / 4) * 3 bytes of - * space. This function will return the number of bytes actually used. + * The buffer data must contain at least ((base64len+3) / 4) * 3 bytes + * of space. This function will return the number of bytes actually + * used. */ size_t otrl_base64_decode(unsigned char *data, const char *base64data, size_t base64len) @@ -234,13 +235,18 @@ return -2; } + /* Skip over the "?OTR:" */ + otrtag += 5; + msglen -= 5; + /* Base64-decode the message */ - rawlen = ((msglen-5) / 4) * 3; /* maximum possible */ + rawlen = OTRL_B64_MAX_DECODED_SIZE(msglen); /* maximum possible */ rawmsg = malloc(rawlen); if (!rawmsg && rawlen > 0) { return -1; } - rawlen = otrl_base64_decode(rawmsg, otrtag+5, msglen-5); /* actual size */ + + rawlen = otrl_base64_decode(rawmsg, otrtag, msglen); /* actual size */ *bufp = rawmsg; *lenp = rawlen; diff -Nru libotr-3.2.0/src/b64.h libotr-3.2.1/src/b64.h --- libotr-3.2.0/src/b64.h 2008-05-27 14:35:28.000000000 +0200 +++ libotr-3.2.1/src/b64.h 2012-08-07 12:21:31.000000000 +0200 @@ -20,6 +20,19 @@ #ifndef __B64_H__ #define __B64_H__ +#include <stdlib.h> + +/* Base64 encodes blocks of this many bytes: */ +#define OTRL_B64_DECODED_LEN 3 +/* into blocks of this many bytes: */ +#define OTRL_B64_ENCODED_LEN 4 + +/* An encoded block of length encoded_len can turn into a maximum of + * this many decoded bytes: */ +#define OTRL_B64_MAX_DECODED_SIZE(encoded_len) \ + (((encoded_len + OTRL_B64_ENCODED_LEN - 1) / OTRL_B64_ENCODED_LEN) \ + * OTRL_B64_DECODED_LEN) + /* * base64 encode data. Insert no linebreaks or whitespace. * @@ -33,8 +46,9 @@ * base64 decode data. Skip non-base64 chars, and terminate at the * first '=', or the end of the buffer. * - * The buffer data must contain at least (base64len / 4) * 3 bytes of - * space. This function will return the number of bytes actually used. + * The buffer data must contain at least ((base64len+3) / 4) * 3 bytes + * of space. This function will return the number of bytes actually + * used. */ size_t otrl_base64_decode(unsigned char *data, const char *base64data, size_t base64len); diff -Nru libotr-3.2.0/src/proto.c libotr-3.2.1/src/proto.c --- libotr-3.2.0/src/proto.c 2008-05-27 14:35:28.000000000 +0200 +++ libotr-3.2.1/src/proto.c 2012-08-07 12:21:31.000000000 +0200 @@ -537,13 +537,17 @@ msglen = strlen(otrtag); } + /* Skip over the "?OTR:" */ + otrtag += 5; + msglen -= 5; + /* Base64-decode the message */ - rawlen = ((msglen-5) / 4) * 3; /* maximum possible */ + rawlen = OTRL_B64_MAX_DECODED_SIZE(msglen); /* maximum possible */ rawmsg = malloc(rawlen); if (!rawmsg && rawlen > 0) { return gcry_error(GPG_ERR_ENOMEM); } - rawlen = otrl_base64_decode(rawmsg, otrtag+5, msglen-5); /* actual size */ + rawlen = otrl_base64_decode(rawmsg, otrtag, msglen); /* actual size */ bufp = rawmsg; lenp = rawlen; @@ -606,14 +610,18 @@ msglen = strlen(otrtag); } + /* Skip over the "?OTR:" */ + otrtag += 5; + msglen -= 5; + /* Base64-decode the message */ - rawlen = ((msglen-5) / 4) * 3; /* maximum possible */ + rawlen = OTRL_B64_MAX_DECODED_SIZE(msglen); /* maximum possible */ rawmsg = malloc(rawlen); if (!rawmsg && rawlen > 0) { err = gcry_error(GPG_ERR_ENOMEM); goto err; } - rawlen = otrl_base64_decode(rawmsg, otrtag+5, msglen-5); /* actual size */ + rawlen = otrl_base64_decode(rawmsg, otrtag, msglen); /* actual size */ bufp = rawmsg; lenp = rawlen; diff -Nru libotr-3.2.0/src/version.h libotr-3.2.1/src/version.h --- libotr-3.2.0/src/version.h 2008-05-27 14:35:28.000000000 +0200 +++ libotr-3.2.1/src/version.h 2012-08-07 12:21:35.000000000 +0200 @@ -20,10 +20,10 @@ #ifndef __VERSION_H__ #define __VERSION_H__ -#define OTRL_VERSION "3.2.0" +#define OTRL_VERSION "3.2.1" #define OTRL_VERSION_MAJOR 3 #define OTRL_VERSION_MINOR 2 -#define OTRL_VERSION_SUB 0 +#define OTRL_VERSION_SUB 1 #endif diff -Nru libotr-3.2.0/toolkit/parse.c libotr-3.2.1/toolkit/parse.c --- libotr-3.2.0/toolkit/parse.c 2008-05-27 14:35:28.000000000 +0200 +++ libotr-3.2.1/toolkit/parse.c 2012-08-07 12:21:33.000000000 +0200 @@ -64,7 +64,8 @@ { const char *header, *footer; unsigned char *raw; - + size_t rawlen; + /* Find the header */ header = strstr(msg, "?OTR:"); if (!header) return NULL; @@ -75,8 +76,10 @@ footer = strchr(header, '.'); if (!footer) footer = header + strlen(header); - raw = malloc((footer-header) / 4 * 3); - if (raw == NULL && (footer-header >= 4)) return NULL; + rawlen = OTRL_B64_MAX_DECODED_SIZE(footer-header); + + raw = malloc(rawlen); + if (raw == NULL && rawlen > 0) return NULL; *lenp = otrl_base64_decode(raw, header, footer-header); return raw;