From bffe05f44cce9d4f948bb1286097cea293a067f6 Mon Sep 17 00:00:00 2001 From: Bruno Haible Date: Mon, 31 Dec 2007 11:53:40 +0100 Subject: [PATCH] Protect against integer overflow in malloca() calls. --- ChangeLog | 12 ++++++++++++ lib/c-strcasestr.c | 2 +- lib/c-strstr.c | 2 +- lib/malloca.h | 16 +++++++++++++--- lib/mbscasestr.c | 4 ++-- lib/mbsstr.c | 4 ++-- lib/memmem.c | 5 +---- lib/strcasestr.c | 2 +- 8 files changed, 33 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5d9655ba27..32c0264e1f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2007-12-30 Bruno Haible + + * lib/malloca.h (nmalloca): New macro. + * lib/c-strcasestr.c (knuth_morris_pratt): Use it. + * lib/c-strstr.c (knuth_morris_pratt): Likewise. + * lib/mbscasestr.c (knuth_morris_pratt_unibyte, + knuth_morris_pratt_multibyte): Likewise. + * lib/mbsstr.c (knuth_morris_pratt_unibyte, + knuth_morris_pratt_multibyte): Likewise. + * lib/memmem.c (knuth_morris_pratt): Likewise. + * lib/strcasestr.c (knuth_morris_pratt): Likewise. + 2007-12-25 Bruno Haible Fixup after 2007-10-17 commit. Ensure that 'glob' stays under LGPLv2+. diff --git a/lib/c-strcasestr.c b/lib/c-strcasestr.c index 76732d20ff..36b2a9f5ce 100644 --- a/lib/c-strcasestr.c +++ b/lib/c-strcasestr.c @@ -37,7 +37,7 @@ knuth_morris_pratt (const char *haystack, const char *needle, size_t m = strlen (needle); /* Allocate the table. */ - size_t *table = (size_t *) malloca (m * sizeof (size_t)); + size_t *table = (size_t *) nmalloca (m, sizeof (size_t)); if (table == NULL) return false; /* Fill the table. diff --git a/lib/c-strstr.c b/lib/c-strstr.c index 58ae2c51cf..3652100e62 100644 --- a/lib/c-strstr.c +++ b/lib/c-strstr.c @@ -36,7 +36,7 @@ knuth_morris_pratt (const char *haystack, const char *needle, size_t m = strlen (needle); /* Allocate the table. */ - size_t *table = (size_t *) malloca (m * sizeof (size_t)); + size_t *table = (size_t *) nmalloca (m, sizeof (size_t)); if (table == NULL) return false; /* Fill the table. diff --git a/lib/malloca.h b/lib/malloca.h index 2f74b96170..5bb2d47348 100644 --- a/lib/malloca.h +++ b/lib/malloca.h @@ -70,9 +70,19 @@ extern void freea (void *p); # define freea free #endif -/* Maybe we should also define a variant - nmalloca (size_t n, size_t s) - behaves like malloca (n * s) - If this would be useful in your application. please speak up. */ +/* nmalloca(N,S) is an overflow-safe variant of malloca (N * S). + It allocates an array of N objects, each with S bytes of memory, + on the stack. S must be positive and N must be nonnegative. + The array must be freed using freea() before the function returns. */ +#if 1 +/* Cf. the definition of xalloc_oversized. */ +# define nmalloca(n, s) \ + ((n) > (size_t) (sizeof (ptrdiff_t) <= sizeof (size_t) ? -1 : -2) / (s) \ + ? NULL \ + : malloca ((n) * (s))) +#else +extern void * nmalloca (size_t n, size_t s); +#endif #ifdef __cplusplus diff --git a/lib/mbscasestr.c b/lib/mbscasestr.c index a5491e4c9b..7205cca1e9 100644 --- a/lib/mbscasestr.c +++ b/lib/mbscasestr.c @@ -42,7 +42,7 @@ knuth_morris_pratt_unibyte (const char *haystack, const char *needle, size_t m = strlen (needle); /* Allocate the table. */ - size_t *table = (size_t *) malloca (m * sizeof (size_t)); + size_t *table = (size_t *) nmalloca (m, sizeof (size_t)); if (table == NULL) return false; /* Fill the table. @@ -164,7 +164,7 @@ knuth_morris_pratt_multibyte (const char *haystack, const char *needle, size_t *table; /* Allocate room for needle_mbchars and the table. */ - char *memory = (char *) malloca (m * (sizeof (mbchar_t) + sizeof (size_t))); + char *memory = (char *) nmalloca (m, sizeof (mbchar_t) + sizeof (size_t)); if (memory == NULL) return false; needle_mbchars = (mbchar_t *) memory; diff --git a/lib/mbsstr.c b/lib/mbsstr.c index f875207184..420be08436 100644 --- a/lib/mbsstr.c +++ b/lib/mbsstr.c @@ -39,7 +39,7 @@ knuth_morris_pratt_unibyte (const char *haystack, const char *needle, size_t m = strlen (needle); /* Allocate the table. */ - size_t *table = (size_t *) malloca (m * sizeof (size_t)); + size_t *table = (size_t *) nmalloca (m, sizeof (size_t)); if (table == NULL) return false; /* Fill the table. @@ -160,7 +160,7 @@ knuth_morris_pratt_multibyte (const char *haystack, const char *needle, size_t *table; /* Allocate room for needle_mbchars and the table. */ - char *memory = (char *) malloca (m * (sizeof (mbchar_t) + sizeof (size_t))); + char *memory = (char *) nmalloca (m, sizeof (mbchar_t) + sizeof (size_t)); if (memory == NULL) return false; needle_mbchars = (mbchar_t *) memory; diff --git a/lib/memmem.c b/lib/memmem.c index b7f3e12c6c..57c6560323 100644 --- a/lib/memmem.c +++ b/lib/memmem.c @@ -39,10 +39,7 @@ knuth_morris_pratt (const char *haystack, const char *last_haystack, const char **resultp) { /* Allocate the table. */ - size_t *table; - if ((size_t) -1 / sizeof (size_t) < m) - return false; - table = (size_t *) malloca (m * sizeof (size_t)); + size_t *table = (size_t *) nmalloca (m, sizeof (size_t)); if (table == NULL) return false; /* Fill the table. diff --git a/lib/strcasestr.c b/lib/strcasestr.c index 27145dd37d..dfbf925b79 100644 --- a/lib/strcasestr.c +++ b/lib/strcasestr.c @@ -39,7 +39,7 @@ knuth_morris_pratt (const char *haystack, const char *needle, size_t m = strlen (needle); /* Allocate the table. */ - size_t *table = (size_t *) malloca (m * sizeof (size_t)); + size_t *table = (size_t *) nmalloca (m, sizeof (size_t)); if (table == NULL) return false; /* Fill the table. -- 2.30.2