# HG changeset patch # User Bruno Haible # Date 1199098420 -3600 # Node ID c487592d112a06734bb8f83fd254e07c927a1752 # Parent 81a0ee2e4e005b3cd88f2d2fdf204ad120c00430 Protect against integer overflow in malloca() calls. diff --git a/ChangeLog b/ChangeLog --- 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 --- a/lib/c-strcasestr.c +++ b/lib/c-strcasestr.c @@ -37,7 +37,7 @@ 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 --- a/lib/c-strstr.c +++ b/lib/c-strstr.c @@ -36,7 +36,7 @@ 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 --- a/lib/malloca.h +++ b/lib/malloca.h @@ -70,9 +70,19 @@ # 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 --- a/lib/mbscasestr.c +++ b/lib/mbscasestr.c @@ -42,7 +42,7 @@ 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 @@ 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 --- a/lib/mbsstr.c +++ b/lib/mbsstr.c @@ -39,7 +39,7 @@ 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 @@ 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 --- a/lib/memmem.c +++ b/lib/memmem.c @@ -39,10 +39,7 @@ 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 --- a/lib/strcasestr.c +++ b/lib/strcasestr.c @@ -39,7 +39,7 @@ 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.