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;

Reply via email to