Fix for CVE-2012-3461 (multiple heap overflows), tested so far with climm on amd64.
Also, taking maintainer for this. Index: Makefile =================================================================== RCS file: /cvs/ports/security/libotr/Makefile,v retrieving revision 1.14 diff -u -p -r1.14 Makefile --- Makefile 4 Apr 2012 06:45:27 -0000 1.14 +++ Makefile 12 Aug 2012 19:31:57 -0000 @@ -5,13 +5,15 @@ COMMENT= portable OTR messaging library DISTNAME= libotr-3.2.0 CATEGORIES= security -REVISION= 0 +REVISION= 1 SHARED_LIBS += otr 3.2 # 4.0 HOMEPAGE= http://www.cypherpunks.ca/otr/ MASTER_SITES= ${HOMEPAGE} + +MAINTAINER = Pascal Stumpf <pascal.stu...@cubes.de> # GPLv2 PERMIT_PACKAGE_CDROM= Yes Index: patches/patch-ChangeLog =================================================================== RCS file: patches/patch-ChangeLog diff -N patches/patch-ChangeLog --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ patches/patch-ChangeLog 12 Aug 2012 19:31:57 -0000 @@ -0,0 +1,15 @@ +$OpenBSD$ + +http://otr.git.sourceforge.net/git/gitweb.cgi?p=otr/libotr;a=commitdiff;h=b17232f86f8e60d0d22caf9a2400494d3c77da58 + +--- ChangeLog.orig Sun Jun 15 22:16:34 2008 ++++ ChangeLog Sun Aug 12 21:14:14 2012 +@@ -1,3 +1,8 @@ ++2012-07-19 ++ ++ * src/b64.[ch], src/proto.c: Clean up the previous b64 patch ++ and apply it to all places where otrl_base64_decode() is called. ++ + 2008-06-15: + + * README: Release version 3.2.0. Index: patches/patch-src_b64_c =================================================================== RCS file: patches/patch-src_b64_c diff -N patches/patch-src_b64_c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ patches/patch-src_b64_c 12 Aug 2012 19:31:57 -0000 @@ -0,0 +1,49 @@ +$OpenBSD$ + +http://otr.git.sourceforge.net/git/gitweb.cgi?p=otr/libotr;a=commitdiff;h=b17232f86f8e60d0d22caf9a2400494d3c77da58 + +http://otr.git.sourceforge.net/git/gitweb.cgi?p=otr/libotr;a=commitdiff;h=6d4ca89cf1d3c9a8aff696c3a846ac5a51f762c1 + +--- src/b64.c.orig Tue May 27 14:35:28 2008 ++++ src/b64.c Sun Aug 12 21:17:21 2012 +@@ -55,7 +55,7 @@ VERSION HISTORY: + \******************************************************************* */ + + /* system headers */ +-#include <stdlib.h> ++#include <stdio.h> + #include <string.h> + + /* libotr headers */ +@@ -147,8 +147,9 @@ static size_t decode(unsigned char *out, const char *i + * 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,17 @@ int otrl_base64_otr_decode(const char *msg, unsigned c + 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; Index: patches/patch-src_b64_h =================================================================== RCS file: patches/patch-src_b64_h diff -N patches/patch-src_b64_h --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ patches/patch-src_b64_h 12 Aug 2012 19:31:57 -0000 @@ -0,0 +1,38 @@ +$OpenBSD$ + +http://otr.git.sourceforge.net/git/gitweb.cgi?p=otr/libotr;a=commitdiff;h=6d4ca89cf1d3c9a8aff696c3a846ac5a51f762c1 + +--- src/b64.h.orig Tue May 27 14:35:28 2008 ++++ src/b64.h Sun Aug 12 21:14:35 2012 +@@ -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 @@ size_t otrl_base64_encode(char *base64data, const unsi + * 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); Index: patches/patch-src_proto_c =================================================================== RCS file: patches/patch-src_proto_c diff -N patches/patch-src_proto_c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ patches/patch-src_proto_c 12 Aug 2012 19:31:57 -0000 @@ -0,0 +1,47 @@ +$OpenBSD$ + +http://otr.git.sourceforge.net/git/gitweb.cgi?p=otr/libotr;a=commitdiff;h=6d4ca89cf1d3c9a8aff696c3a846ac5a51f762c1 + +--- src/proto.c.orig Tue May 27 14:35:28 2008 ++++ src/proto.c Sun Aug 12 21:14:41 2012 +@@ -537,13 +537,17 @@ gcry_error_t otrl_proto_data_read_flags(const char *da + 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 @@ gcry_error_t otrl_proto_accept_data(char **plaintextp, + 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; Index: patches/patch-toolkit_parse_c =================================================================== RCS file: patches/patch-toolkit_parse_c diff -N patches/patch-toolkit_parse_c --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ patches/patch-toolkit_parse_c 12 Aug 2012 19:31:57 -0000 @@ -0,0 +1,29 @@ +$OpenBSD$ + +http://otr.git.sourceforge.net/git/gitweb.cgi?p=otr/libotr;a=commitdiff;h=1902baee5d4b056850274ed0fa8c2409f1187435 + +--- toolkit/parse.c.orig Tue May 27 14:35:28 2008 ++++ toolkit/parse.c Sun Aug 12 21:12:47 2012 +@@ -64,7 +64,8 @@ static unsigned char *decode(const char *msg, size_t * + { + 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 @@ static unsigned char *decode(const char *msg, size_t * + 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;