Avoid zero-length array at the end of struct link_map [BZ #25097]

l_audit ends up as an internal array with _rtld_global, and GCC 10
warns about this.

This commit does not change the layout of _rtld_global, so it is
suitable for backporting.  Future changes could allocate more of the
audit state dynamically and remove it from always-allocated data
structures, to optimize the common case of inactive auditing.

Change-Id: Ic911100730f9124d4ea977ead8e13cee64b84d45
This commit is contained in:
Florian Weimer 2019-11-03 11:20:23 +01:00
parent e1d559f337
commit e21a786771
2 changed files with 23 additions and 12 deletions

View file

@ -325,16 +325,18 @@ struct link_map
size_t l_relro_size;
unsigned long long int l_serial;
/* Audit information. This array apparent must be the last in the
structure. Never add something after it. */
struct auditstate
{
uintptr_t cookie;
unsigned int bindflags;
} l_audit[0];
};
/* Information used by audit modules. For most link maps, this data
immediate follows the link map in memory. For the dynamic linker,
it is allocated separately. See link_map_audit_state in
<ldsodefs.h>. */
struct auditstate
{
uintptr_t cookie;
unsigned int bindflags;
};
#if __ELF_NATIVE_CLASS == 32
# define symbind symbind32

View file

@ -379,11 +379,12 @@ struct rtld_global
/* List of search directories. */
EXTERN struct r_search_path_elem *_dl_all_dirs;
/* Structure describing the dynamic linker itself. We need to
reserve memory for the data the audit libraries need. */
/* Structure describing the dynamic linker itself. */
EXTERN struct link_map _dl_rtld_map;
#ifdef SHARED
struct auditstate audit_data[DL_NNS];
/* Used to store the audit information for the link map of the
dynamic loader. */
struct auditstate _dl_rtld_auditstate[DL_NNS];
#endif
#if defined SHARED && defined _LIBC_REENTRANT \
@ -1178,7 +1179,15 @@ rtld_active (void)
static inline struct auditstate *
link_map_audit_state (struct link_map *l, size_t index)
{
return &l->l_audit[index];
if (l == &GL (dl_rtld_map))
/* The auditstate array is stored separately. */
return &GL (dl_rtld_auditstate) [index];
else
{
/* The auditstate array follows the link map in memory. */
struct auditstate *base = (struct auditstate *) (l + 1);
return &base[index];
}
}
#endif /* SHARED */