summaryrefslogtreecommitdiff
path: root/lib/time_rz.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/time_rz.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/time_rz.c')
-rw-r--r--lib/time_rz.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/lib/time_rz.c b/lib/time_rz.c
index 10a006ca2e..8bfe988479 100644
--- a/lib/time_rz.c
+++ b/lib/time_rz.c
@@ -32,6 +32,7 @@
#include <stdlib.h>
#include <string.h>
+#include "flexmember.h"
#include "time-internal.h"
#if !HAVE_TZSET
@@ -94,7 +95,7 @@ tzalloc (char const *name)
{
size_t name_size = name ? strlen (name) + 1 : 0;
size_t abbr_size = name_size < ABBR_SIZE_MIN ? ABBR_SIZE_MIN : name_size + 1;
- timezone_t tz = malloc (offsetof (struct tm_zone, abbrs) + abbr_size);
+ timezone_t tz = malloc (FLEXSIZEOF (struct tm_zone, abbrs, abbr_size));
if (tz)
{
tz->next = NULL;