--- Begin Message ---
Package: release.debian.org
Severity: normal
User: release.debian.org@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 <jnferguson@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 <varenet@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;
--- End Message ---