Compare commits

...
Author SHA1 Message Date
Florian Weimer 96ab757f9c Redefine _IO_iconv_t to store a single gconv step pointer [BZ #25097]
libio can only deal with gconv conversions which consist of a single
step.  Not using __gconv_info simplifies the data structures somewhat.

This eliminates a new GCC 10 warning about subscribing an inner
zero-length array.

Tested on x86_64-linux-gnu with mainline GCC.  Built with
build-many-glibcs.py, also with mainline GCC.  Due to GCC PR 92039,
there are failures left on 32-bit architectures with float128 support.

Change-Id: I8b4c489b619a53154712ff32e1b6f13bb92d4203
2019-11-03 18:10:20 +01:00
Florian Weimer 7591046cb1 slotinfo in struct dtv_slotinfo_list should be flexible array [BZ #25097]
GCC 10 will warn about subscribing inner length zero arrays.  Use a GCC
extension in csu/libc-tls.c to allocate space for the static_slotinfo
variable.  Adjust nptl_db so that the type description machinery does
not attempt to determine the size of the flexible array member slotinfo.

Change-Id: I51be146a7857186a4ede0bb40b332509487bdde8
2019-11-03 18:10:15 +01:00
Florian Weimer 6a77162141 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
2019-11-03 18:10:11 +01:00
Florian Weimer b1c595cec0 Introduce link_map_audit_state accessor function
To improve GCC 10 compatibility, it is necessary to remove the l_audit
zero-length array from the end of struct link_map.  In preparation of
that, this commit introduces an accessor function for the audit state,
so that it is possible to change the representation of the audit state
without adjusting the code that accesses it.

Tested on x86_64-linux-gnu.  Built on i686-gnu.

Change-Id: Id815673c29950fc011ae5301d7cde12624f658df
2019-11-03 18:10:00 +01:00
Florian Weimer 05efd60143 Properly initialize audit cookie for the dynamic loader [BZ #25157]
The l_audit array is indexed by audit module, not audit function.

Change-Id: I180eb3573dc1c57433750f5d8cb18271460ba5f2
2019-11-03 18:09:52 +01:00
32 changed files with 462 additions and 141 deletions
+1 -1
View File
@@ -272,7 +272,7 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL),
for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
{
if (afct->preinit != NULL)
afct->preinit (&head->l_audit[cnt].cookie);
afct->preinit (&link_map_audit_state (head, cnt)->cookie);
afct = afct->next;
}
+13 -19
View File
@@ -23,7 +23,7 @@
#include <unistd.h>
#include <stdio.h>
#include <sys/param.h>
#include <array_length.h>
#ifdef SHARED
#error makefile bug, this file is for static only
@@ -32,17 +32,11 @@
dtv_t _dl_static_dtv[2 + TLS_SLOTINFO_SURPLUS];
static struct
{
struct dtv_slotinfo_list si;
/* The dtv_slotinfo_list data structure does not include the actual
information since it is defined as an array of size zero. We define
here the necessary entries. Note that it is not important whether
there is padding or not since we will always access the information
through the 'si' element. */
struct dtv_slotinfo info[2 + TLS_SLOTINFO_SURPLUS];
} static_slotinfo;
static struct dtv_slotinfo_list static_slotinfo =
{
/* Allocate an array of 2 + TLS_SLOTINFO_SURPLUS elements. */
.slotinfo = { [array_length (_dl_static_dtv) - 1] = { } },
};
/* Highest dtv index currently needed. */
size_t _dl_tls_max_dtv_idx;
@@ -72,16 +66,16 @@ TLS_INIT_HELPER
static void
init_slotinfo (void)
{
/* Create the slotinfo list. */
static_slotinfo.si.len = (((char *) (&static_slotinfo + 1)
- (char *) &static_slotinfo.si.slotinfo[0])
/ sizeof static_slotinfo.si.slotinfo[0]);
// static_slotinfo.si.next = NULL; already zero
/* Create the slotinfo list. Note that the type of static_slotinfo
has effectively a zero-length array, so we cannot use the size of
static_slotinfo to determine the array length. */
static_slotinfo.len = array_length (_dl_static_dtv);
/* static_slotinfo.si.next = NULL; -- Already zero. */
/* The slotinfo list. Will be extended by the code doing dynamic
linking. */
GL(dl_tls_max_dtv_idx) = 1;
GL(dl_tls_dtv_slotinfo_list) = &static_slotinfo.si;
GL(dl_tls_dtv_slotinfo_list) = &static_slotinfo;
}
static void
@@ -206,7 +200,7 @@ __libc_setup_tls (void)
init_slotinfo ();
// static_slotinfo.si.slotinfo[1].gen = 0; already zero
static_slotinfo.si.slotinfo[1].map = main_map;
static_slotinfo.slotinfo[1].map = main_map;
memsz = roundup (memsz, align ?: 1);
+13 -2
View File
@@ -193,7 +193,7 @@ tests += restest1 preloadtest loadfail multiload origtest resolvfail \
tst-debug1 tst-main1 tst-absolute-sym tst-absolute-zero tst-big-note \
tst-unwind-ctor tst-unwind-main tst-audit13 \
tst-sonamemove-link tst-sonamemove-dlopen tst-dlopen-tlsmodid \
tst-dlopen-self
tst-dlopen-self tst-auditmany
# reldep9
tests-internal += loadtest unload unload2 circleload1 \
neededtest neededtest2 neededtest3 neededtest4 \
@@ -281,7 +281,10 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \
tst-main1mod tst-libc_dlvsym-dso tst-absolute-sym-lib \
tst-absolute-zero-lib tst-big-note-lib tst-unwind-ctor-lib \
tst-audit13mod1 tst-sonamemove-linkmod1 \
tst-sonamemove-runmod1 tst-sonamemove-runmod2
tst-sonamemove-runmod1 tst-sonamemove-runmod2 \
tst-auditmanymod1 tst-auditmanymod2 tst-auditmanymod3 \
tst-auditmanymod4 tst-auditmanymod5 tst-auditmanymod6 \
tst-auditmanymod7 tst-auditmanymod8 tst-auditmanymod9
# Most modules build with _ISOMAC defined, but those filtered out
# depend on internal headers.
modules-names-tests = $(filter-out ifuncmod% tst-libc_dlvsym-dso tst-tlsmod%,\
@@ -1426,6 +1429,14 @@ $(objpfx)tst-audit13.out: $(objpfx)tst-audit13mod1.so
LDFLAGS-tst-audit13mod1.so = -Wl,-z,lazy
tst-audit13-ENV = LD_AUDIT=$(objpfx)tst-audit13mod1.so
$(objpfx)tst-auditmany.out: $(objpfx)tst-auditmanymod1.so \
$(objpfx)tst-auditmanymod2.so $(objpfx)tst-auditmanymod3.so \
$(objpfx)tst-auditmanymod4.so $(objpfx)tst-auditmanymod5.so \
$(objpfx)tst-auditmanymod6.so $(objpfx)tst-auditmanymod7.so \
$(objpfx)tst-auditmanymod8.so $(objpfx)tst-auditmanymod9.so
tst-auditmany-ENV = \
LD_AUDIT=tst-auditmanymod1.so:tst-auditmanymod2.so:tst-auditmanymod3.so:tst-auditmanymod4.so:tst-auditmanymod5.so:tst-auditmanymod6.so:tst-auditmanymod7.so:tst-auditmanymod8.so:tst-auditmanymod9.so
# tst-sonamemove links against an older implementation of the library.
LDFLAGS-tst-sonamemove-linkmod1.so = \
-Wl,--version-script=tst-sonamemove-linkmod1.map \
+14 -4
View File
@@ -302,8 +302,12 @@ _dl_close_worker (struct link_map *map, bool force)
for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
{
if (afct->objclose != NULL)
/* Return value is ignored. */
(void) afct->objclose (&imap->l_audit[cnt].cookie);
{
struct auditstate *state
= link_map_audit_state (imap, cnt);
/* Return value is ignored. */
(void) afct->objclose (&state->cookie);
}
afct = afct->next;
}
@@ -478,7 +482,10 @@ _dl_close_worker (struct link_map *map, bool force)
for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
{
if (afct->activity != NULL)
afct->activity (&head->l_audit[cnt].cookie, LA_ACT_DELETE);
{
struct auditstate *state = link_map_audit_state (head, cnt);
afct->activity (&state->cookie, LA_ACT_DELETE);
}
afct = afct->next;
}
@@ -774,7 +781,10 @@ _dl_close_worker (struct link_map *map, bool force)
for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
{
if (afct->activity != NULL)
afct->activity (&head->l_audit[cnt].cookie, LA_ACT_CONSISTENT);
{
struct auditstate *state = link_map_audit_state (head, cnt);
afct->activity (&state->cookie, LA_ACT_CONSISTENT);
}
afct = afct->next;
}
+6 -3
View File
@@ -152,9 +152,12 @@ _dl_fini (void)
for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
{
if (afct->objclose != NULL)
/* Return value is ignored. */
(void) afct->objclose (&l->l_audit[cnt].cookie);
{
struct auditstate *state
= link_map_audit_state (l, cnt);
/* Return value is ignored. */
(void) afct->objclose (&state->cookie);
}
afct = afct->next;
}
}
+9 -9
View File
@@ -973,7 +973,8 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
{
if (afct->activity != NULL)
afct->activity (&head->l_audit[cnt].cookie, LA_ACT_ADD);
afct->activity (&link_map_audit_state (head, cnt)->cookie,
LA_ACT_ADD);
afct = afct->next;
}
@@ -1402,10 +1403,9 @@ cannot enable executable stack as shared object requires");
{
if (afct->objopen != NULL)
{
l->l_audit[cnt].bindflags
= afct->objopen (l, nsid, &l->l_audit[cnt].cookie);
l->l_audit_any_plt |= l->l_audit[cnt].bindflags != 0;
struct auditstate *state = link_map_audit_state (l, cnt);
state->bindflags = afct->objopen (l, nsid, &state->cookie);
l->l_audit_any_plt |= state->bindflags != 0;
}
afct = afct->next;
@@ -1511,8 +1511,8 @@ open_verify (const char *name, int fd,
{
if (afct->objsearch != NULL)
{
name = afct->objsearch (name, &loader->l_audit[cnt].cookie,
whatcode);
struct auditstate *state = link_map_audit_state (loader, cnt);
name = afct->objsearch (name, &state->cookie, whatcode);
if (name == NULL)
/* Ignore the path. */
return -1;
@@ -1970,8 +1970,8 @@ _dl_map_object (struct link_map *loader, const char *name,
if (afct->objsearch != NULL)
{
const char *before = name;
name = afct->objsearch (name, &loader->l_audit[cnt].cookie,
LA_SER_ORIG);
struct auditstate *state = link_map_audit_state (loader, cnt);
name = afct->objsearch (name, &state->cookie, LA_SER_ORIG);
if (name == NULL)
{
/* Do not try anything further. */
+3 -5
View File
@@ -81,7 +81,7 @@ _dl_new_object (char *realname, const char *libname, int type,
struct link_map *new;
struct libname_list *newname;
#ifdef SHARED
size_t audit_space = naudit * sizeof (new->l_audit[0]);
size_t audit_space = naudit * sizeof (struct auditstate);
#else
# define audit_space 0
#endif
@@ -134,10 +134,8 @@ _dl_new_object (char *realname, const char *libname, int type,
#ifdef SHARED
for (unsigned int cnt = 0; cnt < naudit; ++cnt)
{
new->l_audit[cnt].cookie = (uintptr_t) new;
/* new->l_audit[cnt].bindflags = 0; */
}
/* No need to initialize bindflags due to calloc. */
link_map_audit_state (new, cnt)->cookie = (uintptr_t) new;
#endif
/* new->l_global = 0; We use calloc therefore not necessary. */
+4 -1
View File
@@ -278,7 +278,10 @@ dl_open_worker (void *a)
for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
{
if (afct->activity != NULL)
afct->activity (&head->l_audit[cnt].cookie, LA_ACT_CONSISTENT);
{
struct auditstate *state = link_map_audit_state (head, cnt);
afct->activity (&state->cookie, LA_ACT_CONSISTENT);
}
afct = afct->next;
}
+16 -8
View File
@@ -325,15 +325,18 @@ _dl_profile_fixup (
{
/* XXX Check whether both DSOs must request action or
only one */
if ((l->l_audit[cnt].bindflags & LA_FLG_BINDFROM) != 0
&& (result->l_audit[cnt].bindflags & LA_FLG_BINDTO) != 0)
struct auditstate *l_state = link_map_audit_state (l, cnt);
struct auditstate *result_state
= link_map_audit_state (result, cnt);
if ((l_state->bindflags & LA_FLG_BINDFROM) != 0
&& (result_state->bindflags & LA_FLG_BINDTO) != 0)
{
if (afct->symbind != NULL)
{
uintptr_t new_value
= afct->symbind (&sym, reloc_result->boundndx,
&l->l_audit[cnt].cookie,
&result->l_audit[cnt].cookie,
&l_state->cookie,
&result_state->cookie,
&flags,
strtab2 + defsym->st_name);
if (new_value != (uintptr_t) sym.st_value)
@@ -421,10 +424,13 @@ _dl_profile_fixup (
& (LA_SYMB_NOPLTENTER << (2 * (cnt + 1)))) == 0)
{
long int new_framesize = -1;
struct auditstate *l_state = link_map_audit_state (l, cnt);
struct auditstate *bound_state
= link_map_audit_state (reloc_result->bound, cnt);
uintptr_t new_value
= afct->ARCH_LA_PLTENTER (&sym, reloc_result->boundndx,
&l->l_audit[cnt].cookie,
&reloc_result->bound->l_audit[cnt].cookie,
&l_state->cookie,
&bound_state->cookie,
regs, &flags, symname,
&new_framesize);
if (new_value != (uintptr_t) sym.st_value)
@@ -504,9 +510,11 @@ _dl_call_pltexit (struct link_map *l, ElfW(Word) reloc_arg,
&& (reloc_result->enterexit
& (LA_SYMB_NOPLTEXIT >> (2 * cnt))) == 0)
{
struct auditstate *l_state = link_map_audit_state (l, cnt);
struct auditstate *bound_state
= link_map_audit_state (reloc_result->bound, cnt);
afct->ARCH_LA_PLTEXIT (&sym, reloc_result->boundndx,
&l->l_audit[cnt].cookie,
&reloc_result->bound->l_audit[cnt].cookie,
&l_state->cookie, &bound_state->cookie,
inregs, outregs, symname);
}
+8 -5
View File
@@ -198,17 +198,20 @@ RTLD_NEXT used in code not dynamically loaded"));
for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
{
struct auditstate *match_audit
= link_map_audit_state (match, cnt);
struct auditstate *result_audit
= link_map_audit_state (result, cnt);
if (afct->symbind != NULL
&& ((match->l_audit[cnt].bindflags & LA_FLG_BINDFROM)
!= 0
|| ((result->l_audit[cnt].bindflags & LA_FLG_BINDTO)
&& ((match_audit->bindflags & LA_FLG_BINDFROM) != 0
|| ((result_audit->bindflags & LA_FLG_BINDTO)
!= 0)))
{
unsigned int flags = altvalue | LA_SYMB_DLSYM;
uintptr_t new_value
= afct->symbind (&sym, ndx,
&match->l_audit[cnt].cookie,
&result->l_audit[cnt].cookie,
&match_audit->cookie,
&result_audit->cookie,
&flags, strtab + ref->st_name);
if (new_value != (uintptr_t) sym.st_value)
{
+14 -12
View File
@@ -1008,13 +1008,7 @@ ERROR: audit interface '%s' requires version %d (maximum supported version %d);
/* Store the pointer. */
if (err_str == NULL && largs.result != NULL)
{
newp->fptr[cnt] = largs.result;
/* The dynamic linker link map is statically allocated,
initialize the data now. */
GL(dl_rtld_map).l_audit[cnt].cookie = (intptr_t) &GL(dl_rtld_map);
}
newp->fptr[cnt] = largs.result;
else
newp->fptr[cnt] = NULL;
++cnt;
@@ -1030,6 +1024,12 @@ ERROR: audit interface '%s' requires version %d (maximum supported version %d);
*last_audit = GLRO(dl_audit) = &newp->ifaces;
else
*last_audit = (*last_audit)->next = &newp->ifaces;
/* The dynamic linker link map is statically allocated, so the
cookie in _dl_new_object has not happened. */
link_map_audit_state (&GL (dl_rtld_map), GLRO (dl_naudit))->cookie
= (intptr_t) &GL (dl_rtld_map);
++GLRO(dl_naudit);
/* Mark the DSO as being used for auditing. */
@@ -1046,9 +1046,9 @@ notify_audit_modules_of_loaded_object (struct link_map *map)
{
if (afct->objopen != NULL)
{
map->l_audit[cnt].bindflags
= afct->objopen (map, LM_ID_BASE, &map->l_audit[cnt].cookie);
map->l_audit_any_plt |= map->l_audit[cnt].bindflags != 0;
struct auditstate *state = link_map_audit_state (map, cnt);
state->bindflags = afct->objopen (map, LM_ID_BASE, &state->cookie);
map->l_audit_any_plt |= state->bindflags != 0;
}
afct = afct->next;
@@ -1662,7 +1662,8 @@ ERROR: '%s': cannot process note segment.\n", _dl_argv[0]);
for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
{
if (afct->activity != NULL)
afct->activity (&main_map->l_audit[cnt].cookie, LA_ACT_ADD);
afct->activity (&link_map_audit_state (main_map, cnt)->cookie,
LA_ACT_ADD);
afct = afct->next;
}
@@ -2333,7 +2334,8 @@ ERROR: '%s': cannot process note segment.\n", _dl_argv[0]);
for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
{
if (afct->activity != NULL)
afct->activity (&head->l_audit[cnt].cookie, LA_ACT_CONSISTENT);
afct->activity (&link_map_audit_state (head, cnt)->cookie,
LA_ACT_CONSISTENT);
afct = afct->next;
}
+26
View File
@@ -0,0 +1,26 @@
/* Check cookie initialization for many auditors. Main program.
Copyright (C) 2019 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
/* It does not make sense to use the test harness for this test
because the testing happens in auditors. */
int
main (void)
{
return 0;
}
+64
View File
@@ -0,0 +1,64 @@
/* Check cookie initialization for many auditors. Auditor template.
Copyright (C) 2019 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
/* The macro MOD must be defined to the number of this auditor (an
integer) before including this file. */
#include <link.h>
#include <stdio.h>
#include <unistd.h>
/* Error counter for delayed error reporting. */
static int errors;
unsigned int
la_version (unsigned int version)
{
return version;
}
unsigned int
la_objopen (struct link_map *map, Lmid_t lmid,
uintptr_t *cookie)
{
struct link_map *cookie_map = (struct link_map *) *cookie;
printf ("info: %d, la_objopen: map=%p name=%s cookie=%p:%p diff=%td\n",
MOD, map, map->l_name, cookie, cookie_map,
(char *) cookie - (char *) map);
fflush (stdout);
if (map != cookie_map)
{
printf ("error: %d, la_objopen:"
" map address does not match cookie value\n",
MOD);
fflush (stdout);
++errors;
}
return 0;
}
extern unsigned int
la_objclose (uintptr_t *__cookie)
{
if (errors != 0)
{
printf ("error: exiting due to previous errors");
_exit (1);
}
return 0;
}
+20
View File
@@ -0,0 +1,20 @@
/* Check cookie initialization for many auditors. Auditor 1.
Copyright (C) 2019 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
#define MOD 1
#include "tst-auditmanymod.h"
+20
View File
@@ -0,0 +1,20 @@
/* Check cookie initialization for many auditors. Auditor 2.
Copyright (C) 2019 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
#define MOD 2
#include "tst-auditmanymod.h"
+20
View File
@@ -0,0 +1,20 @@
/* Check cookie initialization for many auditors. Auditor 3.
Copyright (C) 2019 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
#define MOD 3
#include "tst-auditmanymod.h"
+20
View File
@@ -0,0 +1,20 @@
/* Check cookie initialization for many auditors. Auditor 4.
Copyright (C) 2019 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
#define MOD 4
#include "tst-auditmanymod.h"
+20
View File
@@ -0,0 +1,20 @@
/* Check cookie initialization for many auditors. Auditor 5.
Copyright (C) 2019 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
#define MOD 5
#include "tst-auditmanymod.h"
+20
View File
@@ -0,0 +1,20 @@
/* Check cookie initialization for many auditors. Auditor 6.
Copyright (C) 2019 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
#define MOD 6
#include "tst-auditmanymod.h"
+20
View File
@@ -0,0 +1,20 @@
/* Check cookie initialization for many auditors. Auditor 7.
Copyright (C) 2019 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
#define MOD 7
#include "tst-auditmanymod.h"
+20
View File
@@ -0,0 +1,20 @@
/* Check cookie initialization for many auditors. Auditor 8.
Copyright (C) 2019 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
#define MOD 8
#include "tst-auditmanymod.h"
+20
View File
@@ -0,0 +1,20 @@
/* Check cookie initialization for many auditors. Auditor 9.
Copyright (C) 2019 Free Software Foundation, Inc.
This file is part of the GNU C Library.
The GNU C Library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
The GNU C Library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with the GNU C Library; if not, see
<https://www.gnu.org/licenses/>. */
#define MOD 9
#include "tst-auditmanymod.h"
+10 -8
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
+10 -14
View File
@@ -331,23 +331,19 @@ _IO_new_file_fopen (FILE *fp, const char *filename, const char *mode,
cc = fp->_codecvt = &fp->_wide_data->_codecvt;
cc->__cd_in.__cd.__nsteps = fcts.towc_nsteps;
cc->__cd_in.__cd.__steps = fcts.towc;
cc->__cd_in.step = fcts.towc;
cc->__cd_in.__cd.__data[0].__invocation_counter = 0;
cc->__cd_in.__cd.__data[0].__internal_use = 1;
cc->__cd_in.__cd.__data[0].__flags = __GCONV_IS_LAST;
cc->__cd_in.__cd.__data[0].__statep = &result->_wide_data->_IO_state;
cc->__cd_in.step_data.__invocation_counter = 0;
cc->__cd_in.step_data.__internal_use = 1;
cc->__cd_in.step_data.__flags = __GCONV_IS_LAST;
cc->__cd_in.step_data.__statep = &result->_wide_data->_IO_state;
cc->__cd_out.__cd.__nsteps = fcts.tomb_nsteps;
cc->__cd_out.__cd.__steps = fcts.tomb;
cc->__cd_out.step = fcts.tomb;
cc->__cd_out.__cd.__data[0].__invocation_counter = 0;
cc->__cd_out.__cd.__data[0].__internal_use = 1;
cc->__cd_out.__cd.__data[0].__flags
= __GCONV_IS_LAST | __GCONV_TRANSLIT;
cc->__cd_out.__cd.__data[0].__statep =
&result->_wide_data->_IO_state;
cc->__cd_out.step_data.__invocation_counter = 0;
cc->__cd_out.step_data.__internal_use = 1;
cc->__cd_out.step_data.__flags = __GCONV_IS_LAST | __GCONV_TRANSLIT;
cc->__cd_out.step_data.__statep = &result->_wide_data->_IO_state;
/* From now on use the wide character callback functions. */
_IO_JUMPS_FILE_plus (fp) = fp->_wide_data->_wide_vtable;
+2 -2
View File
@@ -62,8 +62,8 @@ _IO_new_fclose (FILE *fp)
struct _IO_codecvt *cc = fp->_codecvt;
__libc_lock_lock (__gconv_lock);
__gconv_release_step (cc->__cd_in.__cd.__steps);
__gconv_release_step (cc->__cd_out.__cd.__steps);
__gconv_release_step (cc->__cd_in.step);
__gconv_release_step (cc->__cd_out.step);
__libc_lock_unlock (__gconv_lock);
}
else
+31 -34
View File
@@ -80,22 +80,19 @@ _IO_fwide (FILE *fp, int mode)
assert (fcts.towc_nsteps == 1);
assert (fcts.tomb_nsteps == 1);
cc->__cd_in.__cd.__nsteps = fcts.towc_nsteps;
cc->__cd_in.__cd.__steps = fcts.towc;
cc->__cd_in.step = fcts.towc;
cc->__cd_in.__cd.__data[0].__invocation_counter = 0;
cc->__cd_in.__cd.__data[0].__internal_use = 1;
cc->__cd_in.__cd.__data[0].__flags = __GCONV_IS_LAST;
cc->__cd_in.__cd.__data[0].__statep = &fp->_wide_data->_IO_state;
cc->__cd_in.step_data.__invocation_counter = 0;
cc->__cd_in.step_data.__internal_use = 1;
cc->__cd_in.step_data.__flags = __GCONV_IS_LAST;
cc->__cd_in.step_data.__statep = &fp->_wide_data->_IO_state;
cc->__cd_out.__cd.__nsteps = fcts.tomb_nsteps;
cc->__cd_out.__cd.__steps = fcts.tomb;
cc->__cd_out.step = fcts.tomb;
cc->__cd_out.__cd.__data[0].__invocation_counter = 0;
cc->__cd_out.__cd.__data[0].__internal_use = 1;
cc->__cd_out.__cd.__data[0].__flags
= __GCONV_IS_LAST | __GCONV_TRANSLIT;
cc->__cd_out.__cd.__data[0].__statep = &fp->_wide_data->_IO_state;
cc->__cd_out.step_data.__invocation_counter = 0;
cc->__cd_out.step_data.__internal_use = 1;
cc->__cd_out.step_data.__flags = __GCONV_IS_LAST | __GCONV_TRANSLIT;
cc->__cd_out.step_data.__statep = &fp->_wide_data->_IO_state;
}
/* From now on use the wide character callback functions. */
@@ -117,14 +114,14 @@ __libio_codecvt_out (struct _IO_codecvt *codecvt, __mbstate_t *statep,
{
enum __codecvt_result result;
struct __gconv_step *gs = codecvt->__cd_out.__cd.__steps;
struct __gconv_step *gs = codecvt->__cd_out.step;
int status;
size_t dummy;
const unsigned char *from_start_copy = (unsigned char *) from_start;
codecvt->__cd_out.__cd.__data[0].__outbuf = (unsigned char *) to_start;
codecvt->__cd_out.__cd.__data[0].__outbufend = (unsigned char *) to_end;
codecvt->__cd_out.__cd.__data[0].__statep = statep;
codecvt->__cd_out.step_data.__outbuf = (unsigned char *) to_start;
codecvt->__cd_out.step_data.__outbufend = (unsigned char *) to_end;
codecvt->__cd_out.step_data.__statep = statep;
__gconv_fct fct = gs->__fct;
#ifdef PTR_DEMANGLE
@@ -133,12 +130,12 @@ __libio_codecvt_out (struct _IO_codecvt *codecvt, __mbstate_t *statep,
#endif
status = DL_CALL_FCT (fct,
(gs, codecvt->__cd_out.__cd.__data, &from_start_copy,
(gs, &codecvt->__cd_out.step_data, &from_start_copy,
(const unsigned char *) from_end, NULL,
&dummy, 0, 0));
*from_stop = (wchar_t *) from_start_copy;
*to_stop = (char *) codecvt->__cd_out.__cd.__data[0].__outbuf;
*to_stop = (char *) codecvt->__cd_out.step_data.__outbuf;
switch (status)
{
@@ -169,14 +166,14 @@ __libio_codecvt_in (struct _IO_codecvt *codecvt, __mbstate_t *statep,
{
enum __codecvt_result result;
struct __gconv_step *gs = codecvt->__cd_in.__cd.__steps;
struct __gconv_step *gs = codecvt->__cd_in.step;
int status;
size_t dummy;
const unsigned char *from_start_copy = (unsigned char *) from_start;
codecvt->__cd_in.__cd.__data[0].__outbuf = (unsigned char *) to_start;
codecvt->__cd_in.__cd.__data[0].__outbufend = (unsigned char *) to_end;
codecvt->__cd_in.__cd.__data[0].__statep = statep;
codecvt->__cd_in.step_data.__outbuf = (unsigned char *) to_start;
codecvt->__cd_in.step_data.__outbufend = (unsigned char *) to_end;
codecvt->__cd_in.step_data.__statep = statep;
__gconv_fct fct = gs->__fct;
#ifdef PTR_DEMANGLE
@@ -185,12 +182,12 @@ __libio_codecvt_in (struct _IO_codecvt *codecvt, __mbstate_t *statep,
#endif
status = DL_CALL_FCT (fct,
(gs, codecvt->__cd_in.__cd.__data, &from_start_copy,
(gs, &codecvt->__cd_in.step_data, &from_start_copy,
(const unsigned char *) from_end, NULL,
&dummy, 0, 0));
*from_stop = (const char *) from_start_copy;
*to_stop = (wchar_t *) codecvt->__cd_in.__cd.__data[0].__outbuf;
*to_stop = (wchar_t *) codecvt->__cd_in.step_data.__outbuf;
switch (status)
{
@@ -217,16 +214,16 @@ int
__libio_codecvt_encoding (struct _IO_codecvt *codecvt)
{
/* See whether the encoding is stateful. */
if (codecvt->__cd_in.__cd.__steps[0].__stateful)
if (codecvt->__cd_in.step->__stateful)
return -1;
/* Fortunately not. Now determine the input bytes for the conversion
necessary for each wide character. */
if (codecvt->__cd_in.__cd.__steps[0].__min_needed_from
!= codecvt->__cd_in.__cd.__steps[0].__max_needed_from)
if (codecvt->__cd_in.step->__min_needed_from
!= codecvt->__cd_in.step->__max_needed_from)
/* Not a constant value. */
return 0;
return codecvt->__cd_in.__cd.__steps[0].__min_needed_from;
return codecvt->__cd_in.step->__min_needed_from;
}
@@ -238,12 +235,12 @@ __libio_codecvt_length (struct _IO_codecvt *codecvt, __mbstate_t *statep,
int result;
const unsigned char *cp = (const unsigned char *) from_start;
wchar_t to_buf[max];
struct __gconv_step *gs = codecvt->__cd_in.__cd.__steps;
struct __gconv_step *gs = codecvt->__cd_in.step;
size_t dummy;
codecvt->__cd_in.__cd.__data[0].__outbuf = (unsigned char *) to_buf;
codecvt->__cd_in.__cd.__data[0].__outbufend = (unsigned char *) &to_buf[max];
codecvt->__cd_in.__cd.__data[0].__statep = statep;
codecvt->__cd_in.step_data.__outbuf = (unsigned char *) to_buf;
codecvt->__cd_in.step_data.__outbufend = (unsigned char *) &to_buf[max];
codecvt->__cd_in.step_data.__statep = statep;
__gconv_fct fct = gs->__fct;
#ifdef PTR_DEMANGLE
@@ -252,7 +249,7 @@ __libio_codecvt_length (struct _IO_codecvt *codecvt, __mbstate_t *statep,
#endif
DL_CALL_FCT (fct,
(gs, codecvt->__cd_in.__cd.__data, &cp,
(gs, &codecvt->__cd_in.step_data, &cp,
(const unsigned char *) from_end, NULL,
&dummy, 0, 0));
+3 -7
View File
@@ -48,14 +48,10 @@
#include <bits/types/wint_t.h>
#include <gconv.h>
typedef union
typedef struct
{
struct __gconv_info __cd;
struct
{
struct __gconv_info __cd;
struct __gconv_step_data __data;
} __combined;
struct __gconv_step *step;
struct __gconv_step_data step_data;
} _IO_iconv_t;
#include <shlib-compat.h>
+3
View File
@@ -25,6 +25,7 @@
DB_LOOKUP_NAME (SYM_SIZEOF_##type, _thread_db_sizeof_##type)
#define DB_STRUCT_FIELD(type, field) \
DB_LOOKUP_NAME (SYM_##type##_FIELD_##field, _thread_db_##type##_##field)
#define DB_STRUCT_FLEXIBLE_ARRAY(type, field) DB_STRUCT_FIELD (type, field)
#define DB_SYMBOL(name) \
DB_LOOKUP_NAME (SYM_##name, name)
#define DB_FUNCTION(name) \
@@ -36,6 +37,8 @@
# include "structs.def"
# undef DB_STRUCT
# undef DB_STRUCT_FIELD
# undef DB_STRUCT_FLEXIBLE_ARRAY
# undef DB_FUNCTION
# undef DB_SYMBOL
# undef DB_VARIABLE
+7 -1
View File
@@ -54,8 +54,11 @@ extern bool __nptl_initial_report_events;
DB_DEFINE_DESC (name, 8 * sizeof (obj), 1, offset);
#define ARRAY_DESC(name, offset, obj) \
DB_DEFINE_DESC (name, \
8 * sizeof (obj)[0], sizeof (obj) / sizeof (obj)[0], \
8 * sizeof (obj)[0], sizeof (obj) / sizeof (obj)[0], \
offset);
/* Flexible arrays do not have a length that can be determined. */
#define FLEXIBLE_ARRAY_DESC(name, offset, obj) \
DB_DEFINE_DESC (name, 8 * sizeof (obj)[0], 0, offset);
#if TLS_TCB_AT_TP
# define dtvp header.dtv
@@ -77,6 +80,9 @@ DESC (_thread_db_pthread_dtvp,
#define DB_STRUCT_ARRAY_FIELD(type, field) \
ARRAY_DESC (_thread_db_##type##_##field, \
offsetof (type, field), ((type *) 0)->field)
#define DB_STRUCT_FLEXIBLE_ARRAY(type, field) \
FLEXIBLE_ARRAY_DESC (_thread_db_##type##_##field, \
offsetof (type, field), ((type *) 0)->field)
#define DB_VARIABLE(name) DESC (_thread_db_##name, 0, name)
#define DB_ARRAY_VARIABLE(name) ARRAY_DESC (_thread_db_##name, 0, name)
#define DB_SYMBOL(name) /* Nothing. */
+1 -1
View File
@@ -110,7 +110,7 @@ DB_RTLD_GLOBAL_FIELD (dl_tls_dtv_slotinfo_list)
DB_STRUCT (dtv_slotinfo_list)
DB_STRUCT_FIELD (dtv_slotinfo_list, len)
DB_STRUCT_FIELD (dtv_slotinfo_list, next)
DB_STRUCT_ARRAY_FIELD (dtv_slotinfo_list, slotinfo)
DB_STRUCT_FLEXIBLE_ARRAY (dtv_slotinfo_list, slotinfo)
DB_STRUCT (dtv_slotinfo)
DB_STRUCT_FIELD (dtv_slotinfo, gen)
+4
View File
@@ -37,12 +37,14 @@ enum
{
# define DB_STRUCT(type) SYM_SIZEOF_##type,
# define DB_STRUCT_FIELD(type, field) SYM_##type##_FIELD_##field,
# define DB_STRUCT_FLEXIBLE_ARRAY(type, field) DB_STRUCT_FIELD (type, field)
# define DB_SYMBOL(name) SYM_##name,
# define DB_FUNCTION(name) SYM_##name,
# define DB_VARIABLE(name) SYM_##name, SYM_DESC_##name,
# include "structs.def"
# undef DB_STRUCT
# undef DB_STRUCT_FIELD
# undef DB_STRUCT_FLEXIBLE_ARRAY
# undef DB_SYMBOL
# undef DB_FUNCTION
# undef DB_VARIABLE
@@ -90,6 +92,7 @@ struct td_thragent
uint32_t ta_sizeof_##type;
# define DB_STRUCT_FIELD(type, field) \
db_desc_t ta_field_##type##_##field;
# define DB_STRUCT_FLEXIBLE_ARRAY(type, field) DB_STRUCT_FIELD (type, field)
# define DB_SYMBOL(name) \
psaddr_t ta_addr_##name;
# define DB_FUNCTION(name) \
@@ -100,6 +103,7 @@ struct td_thragent
# include "structs.def"
# undef DB_STRUCT
# undef DB_STRUCT_FIELD
# undef DB_STRUCT_FLEXIBLE_ARRAY
# undef DB_FUNCTION
# undef DB_SYMBOL
# undef DB_VARIABLE
+20 -5
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 \
@@ -420,7 +421,7 @@ struct rtld_global
{
size_t gen;
struct link_map *map;
} slotinfo[0];
} slotinfo[];
} *_dl_tls_dtv_slotinfo_list;
/* Number of modules in the static TLS block. */
EXTERN size_t _dl_tls_static_nelem;
@@ -1174,7 +1175,21 @@ rtld_active (void)
initialized and active ld.so copy. */
return GLRO(dl_init_all_dirs) != NULL;
}
#endif
static inline struct auditstate *
link_map_audit_state (struct link_map *l, size_t 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 */
__END_DECLS