nightmaremail

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

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:
MMakefile | 17+++++++++--------
Mgen_allocdefs.h | 9+++++++--
Mtests/unittest_stralloc.c | 7+++++++
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);