1From f162d34588669953e6618f329c80a004903aab80 Mon Sep 17 00:00:00 2001
2From: Florian Weimer <fweimer@redhat.com>
3Date: Sat, 2 Nov 2019 20:04:02 +0100
4Subject: [PATCH 13/20] Introduce link_map_audit_state accessor function
5
6To improve GCC 10 compatibility, it is necessary to remove the l_audit
7zero-length array from the end of struct link_map.  In preparation of
8that, this commit introduces an accessor function for the audit state,
9so that it is possible to change the representation of the audit state
10without adjusting the code that accesses it.
11
12Tested on x86_64-linux-gnu.  Built on i686-gnu.
13
14Change-Id: Id815673c29950fc011ae5301d7cde12624f658df
15(cherry picked from commit e1d559f337de2c8ab68a6749dfe873477c883807)
16Signed-off-by: Jeffy Chen <jeffy.chen@rock-chips.com>
17---
18 csu/libc-start.c           |  2 +-
19 elf/dl-close.c             | 18 ++++++++++++++----
20 elf/dl-fini.c              |  9 ++++++---
21 elf/dl-load.c              | 18 +++++++++---------
22 elf/dl-object.c            |  8 +++-----
23 elf/dl-open.c              |  5 ++++-
24 elf/dl-runtime.c           | 24 ++++++++++++++++--------
25 elf/dl-sym.c               | 13 ++++++++-----
26 elf/rtld.c                 | 18 ++++++++++--------
27 sysdeps/generic/ldsodefs.h |  8 +++++++-
28 10 files changed, 78 insertions(+), 45 deletions(-)
29
30diff --git a/csu/libc-start.c b/csu/libc-start.c
31index dd572d53..2b72ae7f 100644
32--- a/csu/libc-start.c
33+++ b/csu/libc-start.c
34@@ -273,7 +273,7 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL),
35       for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
36 	{
37 	  if (afct->preinit != NULL)
38-	    afct->preinit (&head->l_audit[cnt].cookie);
39+	    afct->preinit (&link_map_audit_state (head, cnt)->cookie);
40
41 	  afct = afct->next;
42 	}
43diff --git a/elf/dl-close.c b/elf/dl-close.c
44index ecd67297..40333a23 100644
45--- a/elf/dl-close.c
46+++ b/elf/dl-close.c
47@@ -302,8 +302,12 @@ _dl_close_worker (struct link_map *map, bool force)
48 	      for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
49 		{
50 		  if (afct->objclose != NULL)
51-		    /* Return value is ignored.  */
52-		    (void) afct->objclose (&imap->l_audit[cnt].cookie);
53+		    {
54+		      struct auditstate *state
55+			= link_map_audit_state (imap, cnt);
56+		      /* Return value is ignored.  */
57+		      (void) afct->objclose (&state->cookie);
58+		    }
59
60 		  afct = afct->next;
61 		}
62@@ -478,7 +482,10 @@ _dl_close_worker (struct link_map *map, bool force)
63 	  for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
64 	    {
65 	      if (afct->activity != NULL)
66-		afct->activity (&head->l_audit[cnt].cookie, LA_ACT_DELETE);
67+		{
68+		  struct auditstate *state = link_map_audit_state (head, cnt);
69+		  afct->activity (&state->cookie, LA_ACT_DELETE);
70+		}
71
72 	      afct = afct->next;
73 	    }
74@@ -774,7 +781,10 @@ _dl_close_worker (struct link_map *map, bool force)
75 	  for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
76 	    {
77 	      if (afct->activity != NULL)
78-		afct->activity (&head->l_audit[cnt].cookie, LA_ACT_CONSISTENT);
79+		{
80+		  struct auditstate *state = link_map_audit_state (head, cnt);
81+		  afct->activity (&state->cookie, LA_ACT_CONSISTENT);
82+		}
83
84 	      afct = afct->next;
85 	    }
86diff --git a/elf/dl-fini.c b/elf/dl-fini.c
87index 3cfc2624..915ceb10 100644
88--- a/elf/dl-fini.c
89+++ b/elf/dl-fini.c
90@@ -152,9 +152,12 @@ _dl_fini (void)
91 		      for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
92 			{
93 			  if (afct->objclose != NULL)
94-			    /* Return value is ignored.  */
95-			    (void) afct->objclose (&l->l_audit[cnt].cookie);
96-
97+			    {
98+			      struct auditstate *state
99+				= link_map_audit_state (l, cnt);
100+			      /* Return value is ignored.  */
101+			      (void) afct->objclose (&state->cookie);
102+			    }
103 			  afct = afct->next;
104 			}
105 		    }
106diff --git a/elf/dl-load.c b/elf/dl-load.c
107index c51e4b37..bfe9f5ba 100644
108--- a/elf/dl-load.c
109+++ b/elf/dl-load.c
110@@ -978,7 +978,8 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
111 	      for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
112 		{
113 		  if (afct->activity != NULL)
114-		    afct->activity (&head->l_audit[cnt].cookie, LA_ACT_ADD);
115+		    afct->activity (&link_map_audit_state (head, cnt)->cookie,
116+				    LA_ACT_ADD);
117
118 		  afct = afct->next;
119 		}
120@@ -1391,10 +1392,9 @@ cannot enable executable stack as shared object requires");
121 	{
122 	  if (afct->objopen != NULL)
123 	    {
124-	      l->l_audit[cnt].bindflags
125-		= afct->objopen (l, nsid, &l->l_audit[cnt].cookie);
126-
127-	      l->l_audit_any_plt |= l->l_audit[cnt].bindflags != 0;
128+	      struct auditstate *state = link_map_audit_state (l, cnt);
129+	      state->bindflags = afct->objopen (l, nsid, &state->cookie);
130+	      l->l_audit_any_plt |= state->bindflags != 0;
131 	    }
132
133 	  afct = afct->next;
134@@ -1500,8 +1500,8 @@ open_verify (const char *name, int fd,
135 	{
136 	  if (afct->objsearch != NULL)
137 	    {
138-	      name = afct->objsearch (name, &loader->l_audit[cnt].cookie,
139-				      whatcode);
140+	      struct auditstate *state = link_map_audit_state (loader, cnt);
141+	      name = afct->objsearch (name, &state->cookie, whatcode);
142 	      if (name == NULL)
143 		/* Ignore the path.  */
144 		return -1;
145@@ -1982,8 +1982,8 @@ _dl_map_object (struct link_map *loader, const char *name,
146 	  if (afct->objsearch != NULL)
147 	    {
148 	      const char *before = name;
149-	      name = afct->objsearch (name, &loader->l_audit[cnt].cookie,
150-				      LA_SER_ORIG);
151+	      struct auditstate *state = link_map_audit_state (loader, cnt);
152+	      name = afct->objsearch (name, &state->cookie, LA_SER_ORIG);
153 	      if (name == NULL)
154 		{
155 		  /* Do not try anything further.  */
156diff --git a/elf/dl-object.c b/elf/dl-object.c
157index b37bcc12..b75bb2cd 100644
158--- a/elf/dl-object.c
159+++ b/elf/dl-object.c
160@@ -65,7 +65,7 @@ _dl_new_object (char *realname, const char *libname, int type,
161      auditing libraries and if yes, how many.  Assume the worst.  */
162   unsigned int naudit = GLRO(dl_naudit) ?: ((mode & __RTLD_OPENEXEC)
163 					    ? DL_NNS : 0);
164-  size_t audit_space = naudit * sizeof (new->l_audit[0]);
165+  size_t audit_space = naudit * sizeof (struct auditstate);
166 #else
167 # define audit_space 0
168 #endif
169@@ -106,10 +106,8 @@ _dl_new_object (char *realname, const char *libname, int type,
170
171 #ifdef SHARED
172   for (unsigned int cnt = 0; cnt < naudit; ++cnt)
173-    {
174-      new->l_audit[cnt].cookie = (uintptr_t) new;
175-      /* new->l_audit[cnt].bindflags = 0; */
176-    }
177+    /* No need to initialize bindflags due to calloc.  */
178+    link_map_audit_state (new, cnt)->cookie = (uintptr_t) new;
179 #endif
180
181   /* new->l_global = 0;	We use calloc therefore not necessary.  */
182diff --git a/elf/dl-open.c b/elf/dl-open.c
183index f6c8ef10..44f8ed40 100644
184--- a/elf/dl-open.c
185+++ b/elf/dl-open.c
186@@ -278,7 +278,10 @@ dl_open_worker (void *a)
187 	  for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
188 	    {
189 	      if (afct->activity != NULL)
190-		afct->activity (&head->l_audit[cnt].cookie, LA_ACT_CONSISTENT);
191+		{
192+		  struct auditstate *state = link_map_audit_state (head, cnt);
193+		  afct->activity (&state->cookie, LA_ACT_CONSISTENT);
194+		}
195
196 	      afct = afct->next;
197 	    }
198diff --git a/elf/dl-runtime.c b/elf/dl-runtime.c
199index 3d2f4a7a..72b03e00 100644
200--- a/elf/dl-runtime.c
201+++ b/elf/dl-runtime.c
202@@ -325,15 +325,18 @@ _dl_profile_fixup (
203 		{
204 		  /* XXX Check whether both DSOs must request action or
205 		     only one */
206-		  if ((l->l_audit[cnt].bindflags & LA_FLG_BINDFROM) != 0
207-		      && (result->l_audit[cnt].bindflags & LA_FLG_BINDTO) != 0)
208+		  struct auditstate *l_state = link_map_audit_state (l, cnt);
209+		  struct auditstate *result_state
210+		    = link_map_audit_state (result, cnt);
211+		  if ((l_state->bindflags & LA_FLG_BINDFROM) != 0
212+		      && (result_state->bindflags & LA_FLG_BINDTO) != 0)
213 		    {
214 		      if (afct->symbind != NULL)
215 			{
216 			  uintptr_t new_value
217 			    = afct->symbind (&sym, reloc_result->boundndx,
218-					     &l->l_audit[cnt].cookie,
219-					     &result->l_audit[cnt].cookie,
220+					     &l_state->cookie,
221+					     &result_state->cookie,
222 					     &flags,
223 					     strtab2 + defsym->st_name);
224 			  if (new_value != (uintptr_t) sym.st_value)
225@@ -421,10 +424,13 @@ _dl_profile_fixup (
226 		  & (LA_SYMB_NOPLTENTER << (2 * (cnt + 1)))) == 0)
227 	    {
228 	      long int new_framesize = -1;
229+	      struct auditstate *l_state = link_map_audit_state (l, cnt);
230+	      struct auditstate *bound_state
231+		= link_map_audit_state (reloc_result->bound, cnt);
232 	      uintptr_t new_value
233 		= afct->ARCH_LA_PLTENTER (&sym, reloc_result->boundndx,
234-					  &l->l_audit[cnt].cookie,
235-					  &reloc_result->bound->l_audit[cnt].cookie,
236+					  &l_state->cookie,
237+					  &bound_state->cookie,
238 					  regs, &flags, symname,
239 					  &new_framesize);
240 	      if (new_value != (uintptr_t) sym.st_value)
241@@ -504,9 +510,11 @@ _dl_call_pltexit (struct link_map *l, ElfW(Word) reloc_arg,
242 	  && (reloc_result->enterexit
243 	      & (LA_SYMB_NOPLTEXIT >> (2 * cnt))) == 0)
244 	{
245+	  struct auditstate *l_state = link_map_audit_state (l, cnt);
246+	  struct auditstate *bound_state
247+	    = link_map_audit_state (reloc_result->bound, cnt);
248 	  afct->ARCH_LA_PLTEXIT (&sym, reloc_result->boundndx,
249-				 &l->l_audit[cnt].cookie,
250-				 &reloc_result->bound->l_audit[cnt].cookie,
251+				 &l_state->cookie, &bound_state->cookie,
252 				 inregs, outregs, symname);
253 	}
254
255diff --git a/elf/dl-sym.c b/elf/dl-sym.c
256index 189628ad..286cf7e2 100644
257--- a/elf/dl-sym.c
258+++ b/elf/dl-sym.c
259@@ -198,17 +198,20 @@ RTLD_NEXT used in code not dynamically loaded"));
260
261 	      for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
262 		{
263+		  struct auditstate *match_audit
264+		    = link_map_audit_state (match, cnt);
265+		  struct auditstate *result_audit
266+		    = link_map_audit_state (result, cnt);
267 		  if (afct->symbind != NULL
268-		      && ((match->l_audit[cnt].bindflags & LA_FLG_BINDFROM)
269-			  != 0
270-			  || ((result->l_audit[cnt].bindflags & LA_FLG_BINDTO)
271+		      && ((match_audit->bindflags & LA_FLG_BINDFROM) != 0
272+			  || ((result_audit->bindflags & LA_FLG_BINDTO)
273 			      != 0)))
274 		    {
275 		      unsigned int flags = altvalue | LA_SYMB_DLSYM;
276 		      uintptr_t new_value
277 			= afct->symbind (&sym, ndx,
278-					 &match->l_audit[cnt].cookie,
279-					 &result->l_audit[cnt].cookie,
280+					 &match_audit->cookie,
281+					 &result_audit->cookie,
282 					 &flags, strtab + ref->st_name);
283 		      if (new_value != (uintptr_t) sym.st_value)
284 			{
285diff --git a/elf/rtld.c b/elf/rtld.c
286index 63525ad5..d3b1541d 100644
287--- a/elf/rtld.c
288+++ b/elf/rtld.c
289@@ -1007,9 +1007,9 @@ ERROR: audit interface '%s' requires version %d (maximum supported version %d);
290   else
291     *last_audit = (*last_audit)->next = &newp->ifaces;
292
293-  /* The dynamic linker link map is statically allocated, initialize
294-     the data now.  */
295-  GL (dl_rtld_map).l_audit[GLRO (dl_naudit)].cookie
296+  /* The dynamic linker link map is statically allocated, so the
297+     cookie in _dl_new_object has not happened.  */
298+  link_map_audit_state (&GL (dl_rtld_map), GLRO (dl_naudit))->cookie
299     = (intptr_t) &GL (dl_rtld_map);
300
301   ++GLRO(dl_naudit);
302@@ -1028,9 +1028,9 @@ notify_audit_modules_of_loaded_object (struct link_map *map)
303     {
304       if (afct->objopen != NULL)
305 	{
306-	  map->l_audit[cnt].bindflags
307-	    = afct->objopen (map, LM_ID_BASE, &map->l_audit[cnt].cookie);
308-	  map->l_audit_any_plt |= map->l_audit[cnt].bindflags != 0;
309+	  struct auditstate *state = link_map_audit_state (map, cnt);
310+	  state->bindflags = afct->objopen (map, LM_ID_BASE, &state->cookie);
311+	  map->l_audit_any_plt |= state->bindflags != 0;
312 	}
313
314       afct = afct->next;
315@@ -1642,7 +1642,8 @@ ERROR: '%s': cannot process note segment.\n", _dl_argv[0]);
316       for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
317 	{
318 	  if (afct->activity != NULL)
319-	    afct->activity (&main_map->l_audit[cnt].cookie, LA_ACT_ADD);
320+	    afct->activity (&link_map_audit_state (main_map, cnt)->cookie,
321+			    LA_ACT_ADD);
322
323 	  afct = afct->next;
324 	}
325@@ -2318,7 +2319,8 @@ ERROR: '%s': cannot process note segment.\n", _dl_argv[0]);
326 	  for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
327 	    {
328 	      if (afct->activity != NULL)
329-		afct->activity (&head->l_audit[cnt].cookie, LA_ACT_CONSISTENT);
330+		afct->activity (&link_map_audit_state (head, cnt)->cookie,
331+				LA_ACT_CONSISTENT);
332
333 	      afct = afct->next;
334 	    }
335diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
336index ef7d0e28..910a31e3 100644
337--- a/sysdeps/generic/ldsodefs.h
338+++ b/sysdeps/generic/ldsodefs.h
339@@ -1166,7 +1166,13 @@ rtld_active (void)
340      initialized and active ld.so copy.  */
341   return GLRO(dl_init_all_dirs) != NULL;
342 }
343-#endif
344+
345+static inline struct auditstate *
346+link_map_audit_state (struct link_map *l, size_t index)
347+{
348+  return &l->l_audit[index];
349+}
350+#endif /* SHARED */
351
352 __END_DECLS
353
354--
3552.20.1
356
357