Mercurial > gnulib
diff lib/fts.c @ 18403:4434607ac1ce
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.
author | Paul Eggert <eggert@cs.ucla.edu> |
---|---|
date | Wed, 07 Sep 2016 02:01:42 -0700 |
parents | 7276fe79480b |
children | 12df2165ec1c |
line wrap: on
line diff
--- a/lib/fts.c Tue Sep 06 23:56:26 2016 -0700 +++ b/lib/fts.c Wed Sep 07 02:01:42 2016 -0700 @@ -76,6 +76,7 @@ /* FIXME - use fcntl(F_DUPFD_CLOEXEC)/openat(O_CLOEXEC) once they are supported. */ # include "cloexec.h" +# include "flexmember.h" # include "openat.h" # include "same-inode.h" #endif @@ -1925,17 +1926,7 @@ * The file name is a variable length array. Allocate the FTSENT * structure and the file name in one chunk. */ - len = offsetof(FTSENT, fts_name) + namelen + 1; - /* Align the allocation size so that it works for FTSENT, - so that trailing padding may be referenced by direct access - to the flexible array members, without triggering undefined behavior - by accessing bytes beyond the heap allocation. This implicit access - was seen for example with ISDOT() and GCC 5.1.1 at -O2. - Do not use alignof (FTSENT) here, since C11 prohibits - taking the alignment of a structure containing a flexible - array member. */ - len += alignof (max_align_t) - 1; - len &= ~ (alignof (max_align_t) - 1); + len = FLEXSIZEOF(FTSENT, fts_name, namelen + 1); if ((p = malloc(len)) == NULL) return (NULL);