>From 9211cb3147a1dac2a38a66fb02f24757b7350991 Mon Sep 17 00:00:00 2001 From: Paul Eggert Date: Tue, 22 Aug 2017 10:13:50 -0700 Subject: [PATCH] glob: port to clang's Undefined Sanitizer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Problem reported by Tim Rühsen in: http://lists.gnu.org/archive/html/bug-gnulib/2017-08/msg00144.html * lib/glob.c (FLEXIBLE_ARRAY_MEMBER) [_LIBC]: Define to empty. (glob_in_dir): Do not rely on undefined behavior in accessing struct members beyond their bounds. Use a flexible array member instead. --- ChangeLog | 10 ++++++++++ lib/glob.c | 29 +++++++++++++++-------------- 2 files changed, 25 insertions(+), 14 deletions(-) diff --git a/ChangeLog b/ChangeLog index 98643535f..3753cb2a5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,13 @@ +2017-08-22 Paul Eggert + + glob: port to clang's Undefined Sanitizer + Problem reported by Tim Rühsen in: + http://lists.gnu.org/archive/html/bug-gnulib/2017-08/msg00144.html + * lib/glob.c (FLEXIBLE_ARRAY_MEMBER) [_LIBC]: Define to empty. + (glob_in_dir): Do not rely on undefined behavior in accessing + struct members beyond their bounds. Use a flexible array member + instead. + 2017-08-21 Paul Eggert vc-list-files: port to Solaris 10 diff --git a/lib/glob.c b/lib/glob.c index d06101799..2a7cc8705 100644 --- a/lib/glob.c +++ b/lib/glob.c @@ -75,6 +75,7 @@ # define __stat64(fname, buf) __xstat64 (_STAT_VER, fname, buf) # endif # define struct_stat64 struct stat64 +# define FLEXIBLE_ARRAY_MEMBER #else /* !_LIBC */ # define __getlogin_r(buf, len) getlogin_r (buf, len) # define __stat64(fname, buf) stat (fname, buf) @@ -1590,25 +1591,25 @@ glob_in_dir (const char *pattern, const char *directory, int flags, { size_t dirlen = strlen (directory); void *stream = NULL; - struct globnames - { - struct globnames *next; - size_t count; - char *name[64]; - }; - struct globnames init_names; - struct globnames *names = &init_names; - struct globnames *names_alloca = &init_names; +# define GLOBNAMES_MEMBERS(nnames) \ + struct globnames *next; size_t count; char *name[nnames]; + struct globnames { GLOBNAMES_MEMBERS (FLEXIBLE_ARRAY_MEMBER) }; + struct { GLOBNAMES_MEMBERS (64) } init_names_buf; + struct globnames *init_names = (struct globnames *) &init_names_buf; + struct globnames *names = init_names; + struct globnames *names_alloca = init_names; size_t nfound = 0; size_t cur = 0; int meta; int save; int result; - alloca_used += sizeof (init_names); + alloca_used += sizeof init_names_buf; - init_names.next = NULL; - init_names.count = sizeof init_names.name / sizeof init_names.name[0]; + init_names->next = NULL; + init_names->count = ((sizeof init_names_buf + - offsetof (struct globnames, name)) + / sizeof init_names->name[0]); meta = __glob_pattern_type (pattern, !(flags & GLOB_NOESCAPE)); if (meta == 0 && (flags & (GLOB_NOCHECK|GLOB_NOMAGIC))) @@ -1789,7 +1790,7 @@ glob_in_dir (const char *pattern, const char *directory, int flags, and this is the block assigned to OLD here. */ if (names == NULL) { - assert (old == &init_names); + assert (old == init_names); break; } cur = names->count; @@ -1816,7 +1817,7 @@ glob_in_dir (const char *pattern, const char *directory, int flags, and this is the block assigned to OLD here. */ if (names == NULL) { - assert (old == &init_names); + assert (old == init_names); break; } cur = names->count; -- 2.13.5