This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: [PATCH] dlfcn: Avoid one-element flexible array in Dl_serinfo
- From: Paul Eggert <eggert at cs dot ucla dot edu>
- To: Florian Weimer <fweimer at redhat dot com>
- Cc: libc-alpha at sourceware dot org
- Date: Thu, 23 May 2019 15:42:57 -0700
- Subject: Re: [PATCH] dlfcn: Avoid one-element flexible array in Dl_serinfo
- References: <87k1ehzf7o.fsf@oldenburg2.str.redhat.com>
On 5/23/19 2:34 AM, Florian Weimer wrote:
+# ifdef __GNUC__
+ /* This avoids an unwanted array subscript check by the compiler,
+ while preserving the size of the type. */
+ __extension__ union
+ {
+ Dl_serpath dls_serpath[0]; /* Actually longer, dls_cnt elements. */
+ Dl_serpath __dls_serpath_pad[1];
+ };
+# else /* !__GNUC__ */
Dl_serpath dls_serpath[1]; /* Actually longer, dls_cnt elements. */
+# endif /* !__GNUC__ */
Since this is actually a flexible array member, shouldn't we be using
C99's support for that if available, instead? Something like the
attached untested patch, say. We've been using a FLEXIBLE_ARRAY_MEMBER
macro in Gnulib for quite some time to do this sort of thing.
diff --git a/dlfcn/dlfcn.h b/dlfcn/dlfcn.h
index 896ad6fc9b..01e6fdadc3 100644
--- a/dlfcn/dlfcn.h
+++ b/dlfcn/dlfcn.h
@@ -180,7 +180,7 @@ typedef struct
{
size_t dls_size; /* Size in bytes of the whole buffer. */
unsigned int dls_cnt; /* Number of elements in `dls_serpath'. */
- Dl_serpath dls_serpath[1]; /* Actually longer, dls_cnt elements. */
+ Dl_serpath dls_serpath[__GLIBC_FLEXIBLE_ARRAY_MEMBER /* dls_cnt */];
} Dl_serinfo;
#endif /* __USE_GNU */
diff --git a/include/features.h b/include/features.h
index e016b3e5c7..9942984e57 100644
--- a/include/features.h
+++ b/include/features.h
@@ -141,6 +141,7 @@
#undef __KERNEL_STRICT_NAMES
#undef __GLIBC_USE_DEPRECATED_GETS
#undef __GLIBC_USE_DEPRECATED_SCANF
+#undef __GLIBC_FLEXIBLE_ARRAY_MEMBER
/* Suppress kernel-name space pollution unless user expressedly asks
for it. */
@@ -423,6 +424,15 @@
# define __GLIBC_USE_DEPRECATED_SCANF 0
#endif
+/* 'struct { ...; t m[__GLIBC_FLEXIBLE_ARRAY_MEMBER]; }â?? declares a
+ structure with a flexible array member m at the end in C99 or later,
+ and a structure with a size-1 array member with earlier compilers. */
+#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
+# define __GLIBC_FLEXIBLE_ARRAY_MEMBER
+#else
+# define __GLIBC_FLEXIBLE_ARRAY_MEMBER 1
+#endif
+
/* Get definitions of __STDC_* predefined macros, if the compiler has
not preincluded this header automatically. */
#include <stdc-predef.h>