From patchwork Thu May 23 22:42:57 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Paul Eggert X-Patchwork-Id: 32840 Received: (qmail 4081 invoked by alias); 23 May 2019 22:43:01 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 4060 invoked by uid 89); 23 May 2019 22:43:01 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-15.3 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, SPF_PASS autolearn=ham version=3.3.1 spammy= X-HELO: zimbra.cs.ucla.edu Subject: Re: [PATCH] dlfcn: Avoid one-element flexible array in Dl_serinfo To: Florian Weimer References: <87k1ehzf7o.fsf@oldenburg2.str.redhat.com> From: Paul Eggert Openpgp: preference=signencrypt Cc: libc-alpha@sourceware.org Message-ID: <437469fe-7622-9021-0b0c-5e4a1cdb8482@cs.ucla.edu> Date: Thu, 23 May 2019 15:42:57 -0700 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:60.0) Gecko/20100101 Thunderbird/60.6.1 MIME-Version: 1.0 In-Reply-To: <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