summaryrefslogtreecommitdiff
path: root/lib/fnmatch_loop.c
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2016-09-07 02:01:42 -0700
committerPaul Eggert <eggert@cs.ucla.edu>2016-09-07 02:02:40 -0700
commit4c32543a4f05706ca3a8c8d583a5fb35d0e58828 (patch)
tree79fce850e293ee79f309757a6e7056c7937e82ac /lib/fnmatch_loop.c
parent53270b274701216d863e25518c0ec635a085397f (diff)
downloadgnulib-4c32543a4f05706ca3a8c8d583a5fb35d0e58828.tar.gz
flexmember: port better to GCC + valgrind
With a char[] flexible array member in a struct with nontrivial alignment, GCC-generated code can access past the end of the array, because GCC assumes there are padding bytes to get the struct aligned. So the common idiom of malloc (offsetof (struct s, m), n) does not properly allocate an n-byte trailing member, as malloc’s argument should be the next multiple of alignof (struct s). See GCC Bug#66661: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66661 Although C11 apparently permits this GCC optimization (i.e., there was a bug in Gnulib not in GCC), possibly this is a defect in C11. See the thread containing: https://gcc.gnu.org/ml/gcc-patches/2016-09/msg00317.html * lib/flexmember.h: New file. * lib/fnmatch.c, lib/fts.c, lib/glob.c, lib/idcache.c: * lib/localename.c, lib/time_rz.c: Include flexmember.h. * lib/fnmatch_loop.c (struct patternlist): * lib/localename.c (struct hash_node): Use FLEXIBLE_ARRAY_MEMBER. * lib/fnmatch_loop.c (EXT): * lib/fts.c (fts_alloc): * lib/glob.c (glob_in_dir): * lib/idcache.c (getuser, getuidbyname, getgroup, getgidbyname): * lib/localename.c (gl_lock_define_initialized): * lib/time_rz.c (tzalloc): Use FLEXSIZEOF instead of offsetof. * m4/flexmember.m4 (AC_C_FLEXIBLE_ARRAY_MEMBER): Check that the size of the struct can be taken. * modules/flexmember (Files): Add lib/flexmember.h. * modules/fnmatch, modules/glob, modules/localename (Depends-on): Add flexmember.
Diffstat (limited to 'lib/fnmatch_loop.c')
-rw-r--r--lib/fnmatch_loop.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/lib/fnmatch_loop.c b/lib/fnmatch_loop.c
index a0c00d3456..f41c06f89a 100644
--- a/lib/fnmatch_loop.c
+++ b/lib/fnmatch_loop.c
@@ -1031,7 +1031,7 @@ EXT (INT opt, const CHAR *pattern, const CHAR *string, const CHAR *string_end,
struct patternlist
{
struct patternlist *next;
- CHAR str[1];
+ CHAR str[FLEXIBLE_ARRAY_MEMBER];
} *list = NULL;
struct patternlist **lastp = &list;
size_t pattern_len = STRLEN (pattern);
@@ -1083,7 +1083,7 @@ EXT (INT opt, const CHAR *pattern, const CHAR *string, const CHAR *string_end,
? pattern_len \
: p - startp + 1UL); \
plensize = plen * sizeof (CHAR); \
- newpsize = offsetof (struct patternlist, str) + plensize; \
+ newpsize = FLEXSIZEOF (struct patternlist, str, plensize); \
if ((size_t) -1 / sizeof (CHAR) < plen \
|| newpsize < offsetof (struct patternlist, str) \
|| ALLOCA_LIMIT <= newpsize) \