commit 8038bf6547e85382dcb6696c55bec8d8b127e668
parent 105e01c5cbdd7f042043f595794f12ff8664dda3
Author: Rolf Eike Beer <eike@sf-mail.de>
Date: Fri, 8 May 2020 22:30:58 +0200
genalloc: make sure the new count variable does not overflow
This fixes the most part of CVE-2005-1513.
Diffstat:
3 files changed, 23 insertions(+), 10 deletions(-)
diff --git a/Makefile b/Makefile
@@ -772,7 +772,7 @@ compile ip.c fmt.h scan.h ip.h
ipalloc.o: \
compile ipalloc.c alloc.h gen_allocdefs.h ip.h ipalloc.h ip.h \
-gen_alloc.h oflops.h
+gen_alloc.h oflops.h error.h
./compile ipalloc.c
ipme.o: \
@@ -1027,7 +1027,7 @@ substdio.h exit.h fork.h wait.h env.h sig.h error.h
prioq.o: \
compile prioq.c alloc.h gen_allocdefs.h prioq.h datetime.h \
-gen_alloc.h oflops.h
+gen_alloc.h oflops.h error.h
./compile prioq.c
proc: \
@@ -1145,7 +1145,7 @@ qmail-inject.o: \
compile qmail-inject.c sig.h substdio.h stralloc.h gen_alloc.h \
subfd.h substdio.h sgetopt.h subgetopt.h getln.h alloc.h str.h fmt.h \
hfield.h token822.h gen_alloc.h control.h env.h gen_alloc.h \
-gen_allocdefs.h error.h qmail.h substdio.h now.h datetime.h exit.h \
+gen_allocdefs.h error.h qmail.h substdio.h now.h datetime.h error.h exit.h \
quote.h headerbody.h auto_qmail.h newfield.h stralloc.h constmap.h oflops.h
./compile qmail-inject.c
@@ -1435,7 +1435,8 @@ compile qmail-remote.c sig.h stralloc.h gen_alloc.h substdio.h \
subfd.h substdio.h scan.h case.h error.h auto_qmail.h control.h dns.h \
alloc.h quote.h ip.h ipalloc.h ip.h gen_alloc.h ipme.h ip.h ipalloc.h \
gen_alloc.h gen_allocdefs.h str.h now.h datetime.h exit.h constmap.h \
-tcpto.h readwrite.h timeoutconn.h timeoutread.h timeoutwrite.h oflops.h
+tcpto.h readwrite.h timeoutconn.h timeoutread.h timeoutwrite.h oflops.h \
+error.h
./compile qmail-remote.c
qmail-rspawn: \
@@ -1631,7 +1632,7 @@ qreceipt.o: \
compile qreceipt.c sig.h env.h substdio.h stralloc.h gen_alloc.h \
subfd.h substdio.h getln.h alloc.h str.h hfield.h token822.h \
gen_alloc.h error.h gen_alloc.h gen_allocdefs.h headerbody.h exit.h \
-open.h quote.h qmail.h substdio.h oflops.h
+open.h quote.h qmail.h substdio.h oflops.h error.h
./compile qreceipt.c
qsmhook: \
@@ -1883,7 +1884,7 @@ compile stralloc_copy.c byte.h stralloc.h gen_alloc.h
stralloc_eady.o: \
compile stralloc_eady.c alloc.h stralloc.h gen_alloc.h \
-gen_allocdefs.h oflops.h
+gen_allocdefs.h oflops.h error.h
./compile stralloc_eady.c
stralloc_opyb.o: \
@@ -1896,7 +1897,7 @@ compile stralloc_opys.c byte.h str.h stralloc.h gen_alloc.h
stralloc_pend.o: \
compile stralloc_pend.c alloc.h stralloc.h gen_alloc.h \
-gen_allocdefs.h oflops.h
+gen_allocdefs.h oflops.h error.h
./compile stralloc_pend.c
strerr.a: \
@@ -2012,7 +2013,7 @@ compile timeoutwrite.c timeoutwrite.h select.h error.h readwrite.h
token822.o: \
compile token822.c stralloc.h gen_alloc.h alloc.h str.h token822.h \
-gen_alloc.h gen_allocdefs.h oflops.h
+gen_alloc.h gen_allocdefs.h oflops.h error.h
./compile token822.c
trigger.o: \
diff --git a/gen_allocdefs.h b/gen_allocdefs.h
@@ -2,16 +2,21 @@
#define GEN_ALLOC_DEFS_H
#include "alloc.h"
+#include "error.h"
+#include "oflops.h"
#define GEN_ALLOC_readyplus(ta,type,field,len,a,base,ta_rplus) \
static int ta_rplus ## _internal (ta *x, unsigned int n, unsigned int pluslen) \
{ \
+ errno = error_nomem; \
if (x->field) { \
unsigned int nnum; \
- n += pluslen; \
+ if (__builtin_add_overflow(n, pluslen, &n)) \
+ return 0; \
if (n <= x->a) \
return 1; \
- nnum = base + n + (n >> 3); \
+ if (__builtin_add_overflow(n, (n >> 3) + base, &nnum)) \
+ return 0; \
if (!alloc_re(&x->field,x->a * sizeof(type),nnum * sizeof(type))) \
return 0; \
x->a = nnum; \
diff --git a/tests/unittest_stralloc.c b/tests/unittest_stralloc.c
@@ -64,6 +64,13 @@ START_TEST(test_stralloc_sizes)
ck_assert_uint_eq(thingy.len, strlen(input) + 1);
ck_assert_uint_ge(thingy.a, olen);
+ unsigned int ofl = -30;
+
+ r = stralloc_readyplus(&thingy, ofl);
+ ck_assert_int_eq(r, 0);
+ ck_assert_uint_eq(thingy.len, strlen(input) + 1);
+ ck_assert_uint_ge(thingy.a, olen);
+
ck_assert_str_eq(input, thingy.s);
alloc_free(thingy.s);