Compare commits

...
Author SHA1 Message Date
Szabolcs Nagy fc7beebceb aarch64: Move ld.so _start to separate file and drop _dl_skip_args
A separate asm file is easier to maintain than a macro that expands to
inline asm.

The RTLD_START macro is only needed now because _dl_start is local in
rtld.c, but _start has to call it, if _dl_start was made hidden then it
could be empty.

_dl_skip_args is no longer needed.

---
v4:
- adjust commit message about _dl_skip_args.
v3:
- mention _dl_skip_args
v2:
- fix typo in commit message.
2022-05-04 16:11:57 +01:00
Szabolcs Nagy 3f32aa2bdd linux: Add a getauxval test [BZ #23293]
This is for bug 23293 and it relies on the glibc test system running
tests via explicit ld.so invokation by default.

Reviewed-by: Florian Weimer <fweimer@redhat.com>

---
v4:
- New patch.
2022-05-04 16:11:57 +01:00
Szabolcs Nagy 8db827d67c rtld: Remove DL_ARGV_NOT_RELRO
This is no longer needed because _dl_skip_args is always 0, so the
target specific code that modifies argv after relro protection is
applied is no longer used.

After the patch relro protection is applied to _dl_argv consistently
on all targets.

Reviewed-by: Florian Weimer <fweimer@redhat.com>
Tested-by: Florian Weimer <fweimer@redhat.com>

---
v4:
- New patch.
2022-05-04 16:11:57 +01:00
Szabolcs Nagy 73fd4d7115 rtld: Use generic argv adjustment in ld.so [BZ #23293]
When an executable is invoked as

  ./ld.so [ld.so-args] ./exe [exe-args]

then the argv is adujusted in ld.so before calling the entry point of
the executable so ld.so args are not visible to it.  On most targets
this requires moving argv, env and auxv on the stack to ensure correct
stack alignment at the entry point.  This had several issues:

- The code for this adjustment on the stack is written in asm as part
  of the target specific ld.so _start code which is hard to maintain.

- The adjustment is done after _dl_start returns, where it's too late
  to update GLRO(dl_auxv), as it is already readonly, so it points to
  memory that was clobbered by the adjustment. This is bug 23293.

- _environ is also wrong in ld.so after the adjustment, but it is
  likely not used after _dl_start returns so this is not user visible.

- _dl_argv was updated, but for this it was moved out of relro, which
  changes security properties across targets unnecessarily.

This patch introduces a generic _dl_start_args_adjust function that
handles the argument adjustments after ld.so processed its own args
and before relro protection is applied.  The initial sp at ld.so entry
is passed down to dl_main so it can do the adjustment.

The same algorithm is used on all targets, _dl_skip_args is now 0, so
existing target specific adjustment code is no longer used.  The bug
affects aarch64, alpha, arc, arm, csky, ia64, nios2, s390-32 and sparc,
other targets don't need the change in principle, but it does not hurt
and makes the behaviour more consistent.

The GNU Hurd start code needed some changes, because it relied on
_dl_skip_args after dl_main returned.

Follow up patches can remove _dl_skip_args and DL_ARGV_NOT_RELRO.

---
v5:
- Hurd specific changes.
v4:
- New code is unconditionally used on all targets.
- Hide auxv adjustments behind HAVE_AUX_VECTOR.
- DL_NEED_START_ARGS_ADJUST macro is removed.
- _dl_skip_args is no longer unused.
- start_argptr is passed down to dl_main instead of using a global.
- moved aarch64 DL_ARGV_NOT_RELRO removal to separate patch.
v2:
- use p != NULL, and a_type != AT_NULL
- remove the confusing paragraph from the commit message.
2022-05-04 16:11:57 +01:00
19 changed files with 224 additions and 265 deletions
+68 -22
View File
@@ -157,16 +157,9 @@ static void dl_main_state_init (struct dl_main_state *state);
extern char **_environ attribute_hidden;
static void process_envvars (struct dl_main_state *state);
#ifdef DL_ARGV_NOT_RELRO
int _dl_argc attribute_hidden;
char **_dl_argv = NULL;
/* Nonzero if we were run directly. */
unsigned int _dl_skip_args attribute_hidden;
#else
int _dl_argc attribute_relro attribute_hidden;
char **_dl_argv attribute_relro = NULL;
unsigned int _dl_skip_args attribute_relro attribute_hidden;
#endif
rtld_hidden_data_def (_dl_argv)
#ifndef THREAD_SET_STACK_GUARD
@@ -397,7 +390,8 @@ extern struct rtld_global_ro _rtld_local_ro
static void dl_main (const ElfW(Phdr) *phdr, ElfW(Word) phnum,
ElfW(Addr) *user_entry, ElfW(auxv_t) *auxv);
ElfW(Addr) *user_entry, ElfW(auxv_t) *auxv,
void **start_argptr);
/* These two variables cannot be moved into .data.rel.ro. */
static struct libname_list _dl_rtld_libname;
@@ -1306,11 +1300,60 @@ rtld_setup_main_map (struct link_map *main_map)
return has_interp;
}
static void
_dl_start_args_adjust (void **start_argptr, int skip_args)
{
void **sp = start_argptr;
void **p;
long argc;
char **argv;
if (skip_args == 0)
return;
/* Adjust argc on stack. */
argc = (long) sp[0] - skip_args;
sp[0] = (void *) argc;
argv = (char **) (sp + 1); /* Necessary aliasing violation. */
p = sp + skip_args;
/* Shuffle argv down. */
do
*++sp = *++p;
while (*p != NULL);
/* Shuffle envp down. */
do
*++sp = *++p;
while (*p != NULL);
/* Update globals in rtld. */
_dl_argv = argv;
_environ = argv + argc + 1;
#ifdef HAVE_AUX_VECTOR
GLRO(dl_auxv) = (ElfW(auxv_t) *) (sp + 1); /* Aliasing violation. */
/* Shuffle auxv down. */
void *a, *b; /* Use a pair of pointers for an auxv entry. */
unsigned long a_type;
do
{
a_type = ((ElfW(auxv_t) *) (p + 1))->a_type;
a = *++p;
b = *++p;
*++sp = a;
*++sp = b;
}
while (a_type != AT_NULL);
#endif
}
static void
dl_main (const ElfW(Phdr) *phdr,
ElfW(Word) phnum,
ElfW(Addr) *user_entry,
ElfW(auxv_t) *auxv)
ElfW(auxv_t) *auxv,
void **start_argptr)
{
struct link_map *main_map;
size_t file_size;
@@ -1359,6 +1402,7 @@ dl_main (const ElfW(Phdr) *phdr,
rtld_is_main = true;
char *argv0 = NULL;
int skip_args = 0;
/* Note the place where the dynamic linker actually came from. */
GL(dl_rtld_map).l_name = rtld_progname;
@@ -1373,7 +1417,7 @@ dl_main (const ElfW(Phdr) *phdr,
GLRO(dl_lazy) = -1;
}
++_dl_skip_args;
++skip_args;
--_dl_argc;
++_dl_argv;
}
@@ -1382,14 +1426,14 @@ dl_main (const ElfW(Phdr) *phdr,
if (state.mode != rtld_mode_help)
state.mode = rtld_mode_verify;
++_dl_skip_args;
++skip_args;
--_dl_argc;
++_dl_argv;
}
else if (! strcmp (_dl_argv[1], "--inhibit-cache"))
{
GLRO(dl_inhibit_cache) = 1;
++_dl_skip_args;
++skip_args;
--_dl_argc;
++_dl_argv;
}
@@ -1399,7 +1443,7 @@ dl_main (const ElfW(Phdr) *phdr,
state.library_path = _dl_argv[2];
state.library_path_source = "--library-path";
_dl_skip_args += 2;
skip_args += 2;
_dl_argc -= 2;
_dl_argv += 2;
}
@@ -1408,7 +1452,7 @@ dl_main (const ElfW(Phdr) *phdr,
{
GLRO(dl_inhibit_rpath) = _dl_argv[2];
_dl_skip_args += 2;
skip_args += 2;
_dl_argc -= 2;
_dl_argv += 2;
}
@@ -1416,14 +1460,14 @@ dl_main (const ElfW(Phdr) *phdr,
{
audit_list_add_string (&state.audit_list, _dl_argv[2]);
_dl_skip_args += 2;
skip_args += 2;
_dl_argc -= 2;
_dl_argv += 2;
}
else if (! strcmp (_dl_argv[1], "--preload") && _dl_argc > 2)
{
state.preloadarg = _dl_argv[2];
_dl_skip_args += 2;
skip_args += 2;
_dl_argc -= 2;
_dl_argv += 2;
}
@@ -1431,7 +1475,7 @@ dl_main (const ElfW(Phdr) *phdr,
{
argv0 = _dl_argv[2];
_dl_skip_args += 2;
skip_args += 2;
_dl_argc -= 2;
_dl_argv += 2;
}
@@ -1439,7 +1483,7 @@ dl_main (const ElfW(Phdr) *phdr,
&& _dl_argc > 2)
{
state.glibc_hwcaps_prepend = _dl_argv[2];
_dl_skip_args += 2;
skip_args += 2;
_dl_argc -= 2;
_dl_argv += 2;
}
@@ -1447,7 +1491,7 @@ dl_main (const ElfW(Phdr) *phdr,
&& _dl_argc > 2)
{
state.glibc_hwcaps_mask = _dl_argv[2];
_dl_skip_args += 2;
skip_args += 2;
_dl_argc -= 2;
_dl_argv += 2;
}
@@ -1456,7 +1500,7 @@ dl_main (const ElfW(Phdr) *phdr,
{
state.mode = rtld_mode_list_tunables;
++_dl_skip_args;
++skip_args;
--_dl_argc;
++_dl_argv;
}
@@ -1465,7 +1509,7 @@ dl_main (const ElfW(Phdr) *phdr,
{
state.mode = rtld_mode_list_diagnostics;
++_dl_skip_args;
++skip_args;
--_dl_argc;
++_dl_argv;
}
@@ -1511,7 +1555,7 @@ dl_main (const ElfW(Phdr) *phdr,
_dl_usage (ld_so_name, NULL);
}
++_dl_skip_args;
++skip_args;
--_dl_argc;
++_dl_argv;
@@ -1610,6 +1654,8 @@ dl_main (const ElfW(Phdr) *phdr,
/* Set the argv[0] string now that we've processed the executable. */
if (argv0 != NULL)
_dl_argv[0] = argv0;
/* Adjust arguments for the application entry point. */
_dl_start_args_adjust (start_argptr, skip_args);
}
else
{
+1
View File
@@ -33,6 +33,7 @@ tst-audit27-ENV = LD_AUDIT=$(objpfx)tst-auditmod27.so
endif
ifeq ($(subdir),elf)
sysdep-rtld-routines += dl-start
sysdep-dl-routines += tlsdesc dl-tlsdesc
gen-as-const-headers += dl-link.sym
+2 -75
View File
@@ -105,81 +105,8 @@ elf_machine_runtime_setup (struct link_map *l, struct r_scope_elem *scope[],
return lazy;
}
/* Initial entry point for the dynamic linker. The C function
_dl_start is the real entry point, its return value is the user
program's entry point */
#ifdef __LP64__
# define RTLD_START RTLD_START_1 ("x", "3", "sp")
#else
# define RTLD_START RTLD_START_1 ("w", "2", "wsp")
#endif
#define RTLD_START_1(PTR, PTR_SIZE_LOG, PTR_SP) asm ("\
.text \n\
.globl _start \n\
.type _start, %function \n\
.globl _dl_start_user \n\
.type _dl_start_user, %function \n\
_start: \n\
// bti c \n\
hint 34 \n\
mov " PTR "0, " PTR_SP " \n\
bl _dl_start \n\
// returns user entry point in x0 \n\
mov x21, x0 \n\
_dl_start_user: \n\
// get the original arg count \n\
ldr " PTR "1, [sp] \n\
// get the argv address \n\
add " PTR "2, " PTR_SP ", #(1<<" PTR_SIZE_LOG ") \n\
// get _dl_skip_args to see if we were \n\
// invoked as an executable \n\
adrp x4, _dl_skip_args \n\
ldr w4, [x4, #:lo12:_dl_skip_args] \n\
// do we need to adjust argc/argv \n\
cmp w4, 0 \n\
beq .L_done_stack_adjust \n\
// subtract _dl_skip_args from original arg count \n\
sub " PTR "1, " PTR "1, " PTR "4 \n\
// store adjusted argc back to stack \n\
str " PTR "1, [sp] \n\
// find the first unskipped argument \n\
mov " PTR "3, " PTR "2 \n\
add " PTR "4, " PTR "2, " PTR "4, lsl #" PTR_SIZE_LOG " \n\
// shuffle argv down \n\
1: ldr " PTR "5, [x4], #(1<<" PTR_SIZE_LOG ") \n\
str " PTR "5, [x3], #(1<<" PTR_SIZE_LOG ") \n\
cmp " PTR "5, #0 \n\
bne 1b \n\
// shuffle envp down \n\
1: ldr " PTR "5, [x4], #(1<<" PTR_SIZE_LOG ") \n\
str " PTR "5, [x3], #(1<<" PTR_SIZE_LOG ") \n\
cmp " PTR "5, #0 \n\
bne 1b \n\
// shuffle auxv down \n\
1: ldp " PTR "0, " PTR "5, [x4, #(2<<" PTR_SIZE_LOG ")]! \n\
stp " PTR "0, " PTR "5, [x3], #(2<<" PTR_SIZE_LOG ") \n\
cmp " PTR "0, #0 \n\
bne 1b \n\
// Update _dl_argv \n\
adrp x3, __GI__dl_argv \n\
str " PTR "2, [x3, #:lo12:__GI__dl_argv] \n\
.L_done_stack_adjust: \n\
// compute envp \n\
add " PTR "3, " PTR "2, " PTR "1, lsl #" PTR_SIZE_LOG " \n\
add " PTR "3, " PTR "3, #(1<<" PTR_SIZE_LOG ") \n\
adrp x16, _rtld_local \n\
add " PTR "16, " PTR "16, #:lo12:_rtld_local \n\
ldr " PTR "0, [x16] \n\
bl _dl_init \n\
// load the finalizer function \n\
adrp x0, _dl_fini \n\
add " PTR "0, " PTR "0, #:lo12:_dl_fini \n\
// jump to the user_s entry point \n\
mov x16, x21 \n\
br x16 \n\
");
/* In elf/rtld.c _dl_start should be global so dl-start.S can reference it. */
#define RTLD_START asm (".globl _dl_start");
#define elf_machine_type_class(type) \
((((type) == AARCH64_R(JUMP_SLOT) \
+53
View File
@@ -0,0 +1,53 @@
/* ld.so _start code.
Copyright (C) 2022 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/>. */
#include <sysdep.h>
ENTRY (_start)
/* Create an initial frame with 0 LR and FP */
cfi_undefined (x30)
mov x29, #0
mov x30, #0
mov x0, sp
PTR_ARG (0)
bl _dl_start
/* Returns user entry point in x0. */
mov PTR_REG (21), PTR_REG (0)
.globl _dl_start_user
.type _dl_start_user, %function
_dl_start_user:
/* Get argc. */
ldr PTR_REG (1), [sp]
/* Get argv. */
add x2, sp, PTR_SIZE
/* Compute envp. */
add PTR_REG (3), PTR_REG (2), PTR_REG (1), lsl PTR_LOG_SIZE
add PTR_REG (3), PTR_REG (3), PTR_SIZE
adrp x16, _rtld_local
add PTR_REG (16), PTR_REG (16), :lo12:_rtld_local
ldr PTR_REG (0), [x16]
bl _dl_init
/* Load the finalizer function. */
adrp x0, _dl_fini
add PTR_REG (0), PTR_REG (0), :lo12:_dl_fini
/* Jump to the user's entry point. */
mov x16, x21
br x16
END (_start)
-4
View File
@@ -18,8 +18,4 @@
#include_next <dl-sysdep.h>
/* _dl_argv cannot be attribute_relro, because _dl_start_user
might write into it after _dl_start returns. */
#define DL_ARGV_NOT_RELRO 1
#define DL_EXTERN_PROTECTED_DATA
-23
View File
@@ -1,23 +0,0 @@
/* System-specific settings for dynamic linker code. Alpha version.
Copyright (C) 2002-2022 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/>. */
#include_next <dl-sysdep.h>
/* _dl_argv cannot be attribute_relro, because _dl_start_user
might write into it after _dl_start returns. */
#define DL_ARGV_NOT_RELRO 1
-4
View File
@@ -18,8 +18,4 @@
#include_next <dl-sysdep.h>
/* _dl_argv cannot be attribute_relro, because _dl_start_user
might write into it after _dl_start returns. */
#define DL_ARGV_NOT_RELRO 1
#define DL_EXTERN_PROTECTED_DATA
-4
View File
@@ -18,8 +18,4 @@
#include_next <dl-sysdep.h>
/* _dl_argv cannot be attribute_relro, because _dl_start_user
might write into it after _dl_start returns. */
#define DL_ARGV_NOT_RELRO 1
#define DL_EXTERN_PROTECTED_DATA
-23
View File
@@ -1,23 +0,0 @@
/* System-specific settings for dynamic linker code. C-SKY version.
Copyright (C) 2018-2022 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/>. */
#include_next <dl-sysdep.h>
/* _dl_argv cannot be attribute_relro, because _dl_start_user
might write into it after _dl_start returns. */
#define DL_ARGV_NOT_RELRO 1
+4 -11
View File
@@ -762,18 +762,10 @@ rtld_hidden_proto (__libc_stack_end)
/* Parameters passed to the dynamic linker. */
extern int _dl_argc attribute_hidden attribute_relro;
extern char **_dl_argv
#ifndef DL_ARGV_NOT_RELRO
attribute_relro
#endif
;
extern char **_dl_argv attribute_relro;
rtld_hidden_proto (_dl_argv)
#if IS_IN (rtld)
extern unsigned int _dl_skip_args attribute_hidden
# ifndef DL_ARGV_NOT_RELRO
attribute_relro
# endif
;
extern unsigned int _dl_skip_args attribute_hidden attribute_relro;
#endif
#define rtld_progname _dl_argv[0]
@@ -1165,7 +1157,8 @@ extern ElfW(Addr) _dl_sysdep_start (void **start_argptr,
void (*dl_main) (const ElfW(Phdr) *phdr,
ElfW(Word) phnum,
ElfW(Addr) *user_entry,
ElfW(auxv_t) *auxv))
ElfW(auxv_t) *auxv,
void **start_argptr))
attribute_hidden;
extern void _dl_sysdep_start_cleanup (void) attribute_hidden;
-23
View File
@@ -1,23 +0,0 @@
/* System-specific settings for dynamic linker code. IA-64 version.
Copyright (C) 2002-2022 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/>. */
#include_next <dl-sysdep.h>
/* _dl_argv cannot be attribute_relro, because _dl_start_user
might write into it after _dl_start returns. */
#define DL_ARGV_NOT_RELRO 1
+18 -20
View File
@@ -72,10 +72,11 @@ ElfW(Addr)
_dl_sysdep_start (void **start_argptr,
void (*dl_main) (const ElfW(Phdr) *phdr, ElfW(Word) phent,
ElfW(Addr) *user_entry,
ElfW(auxv_t) *auxv))
ElfW(auxv_t) *auxv, void **start_argptr))
{
void go (intptr_t *argdata)
{
char *orig_argv0;
char **p;
/* Cache the information in various global variables. */
@@ -84,6 +85,8 @@ _dl_sysdep_start (void **start_argptr,
_environ = &_dl_argv[_dl_argc + 1];
for (p = _environ; *p++;); /* Skip environ pointers and terminator. */
orig_argv0 = _dl_argv[0];
if ((void *) p == _dl_argv[0])
{
static struct hurd_startup_data nodata;
@@ -169,34 +172,29 @@ _dl_sysdep_start (void **start_argptr,
up and leave us to transfer control to USER_ENTRY. */
(*dl_main) ((const ElfW(Phdr) *) _dl_hurd_data->phdr,
_dl_hurd_data->phdrsz / sizeof (ElfW(Phdr)),
(ElfW(Addr) *) &_dl_hurd_data->user_entry, NULL);
(ElfW(Addr) *) &_dl_hurd_data->user_entry, NULL,
(void **) argdata);
/* The call above might screw a few things up.
First of all, if _dl_skip_args is nonzero, we are ignoring
the first few arguments. However, if we have no Hurd startup
data, it is the magical convention that ARGV[0] == P. The
P is the location after the terminating NULL of the list of
environment variables. It has to point to the Hurd startup
data or if that's missing then P == ARGV[0] must hold. The
startup code in init-first.c will get confused if this is not
the case, so we must rearrange things to make it so. We'll
overwrite the origional ARGV[0] at P with ARGV[_dl_skip_args].
recompute P and move the Hurd data or the new ARGV[0] there.
Secondly, if we need to be secure, it removes some dangerous
environment variables. If we have no Hurd startup date this
changes P (since that's the location after the terminating
NULL in the list of environment variables). We do the same
thing as in the first case but make sure we recalculate P.
If we do have Hurd startup data, we have to move the data
such that it starts just after the terminating NULL in the
environment list.
Note: directly invoked ld.so can move arguments and env vars
or in secure mode it can remove dangerous env vars.
We use memmove, since the locations might overlap. */
if (__libc_enable_secure || _dl_skip_args)
char **newp;
for (newp = _environ; *newp++;);
if (newp != p || _dl_argv[0] != orig_argv0)
{
char **newp;
for (newp = _environ; *newp++;);
if (_dl_argv[-_dl_skip_args] == (char *) p)
if (orig_argv0 == (char *) p)
{
if ((char *) newp != _dl_argv[0])
{
-4
View File
@@ -18,8 +18,4 @@
#include_next <dl-sysdep.h>
/* _dl_argv cannot be attribute_relro, because _dl_start_user
might write into it after _dl_start returns. */
#define DL_ARGV_NOT_RELRO 1
#define DL_EXTERN_PROTECTED_DATA
-23
View File
@@ -1,23 +0,0 @@
/* System-specific settings for dynamic linker code. S/390 version.
Copyright (C) 2014-2022 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/>. */
#include_next <dl-sysdep.h>
/* _dl_argv cannot be attribute_relro, because _dl_start_user
might write into it after _dl_start returns. */
#define DL_ARGV_NOT_RELRO 1
-23
View File
@@ -1,23 +0,0 @@
/* System-specific settings for dynamic linker code. SPARC version.
Copyright (C) 2002-2022 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/>. */
#include_next <dl-sysdep.h>
/* _dl_argv cannot be attribute_relro, because _dl_start_user
might write into it after _dl_start returns. */
#define DL_ARGV_NOT_RELRO 1
+1
View File
@@ -126,6 +126,7 @@ tests += tst-clone tst-clone2 tst-clone3 tst-fanotify tst-personality \
tst-prctl \
tst-scm_rights \
tst-epoll \
tst-getauxval \
# tests
# For +depfiles in Makerules.
+3 -2
View File
@@ -98,7 +98,8 @@ _dl_sysdep_parse_arguments (void **start_argptr,
ElfW(Addr)
_dl_sysdep_start (void **start_argptr,
void (*dl_main) (const ElfW(Phdr) *phdr, ElfW(Word) phnum,
ElfW(Addr) *user_entry, ElfW(auxv_t) *auxv))
ElfW(Addr) *user_entry, ElfW(auxv_t) *auxv,
void **start_argptr))
{
__libc_stack_end = DL_STACK_END (start_argptr);
@@ -138,7 +139,7 @@ _dl_sysdep_start (void **start_argptr,
__libc_check_standard_fds ();
(*dl_main) (dl_main_args.phdr, dl_main_args.phnum,
&dl_main_args.user_entry, GLRO(dl_auxv));
&dl_main_args.user_entry, GLRO(dl_auxv), start_argptr);
return dl_main_args.user_entry;
}
-4
View File
@@ -48,8 +48,4 @@ extern int _dl_sysinfo_break attribute_hidden;
".previous");
#endif
/* _dl_argv cannot be attribute_relro, because _dl_start_user
might write into it after _dl_start returns. */
#define DL_ARGV_NOT_RELRO 1
#endif /* dl-sysdep.h */
+74
View File
@@ -0,0 +1,74 @@
/* Basic test for getauxval.
Copyright (C) 2022 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/>. */
#include <unistd.h>
#include <stdio.h>
#include <support/check.h>
#include <sys/auxv.h>
static int missing;
static int mismatch;
static void
check_nonzero (unsigned long t, const char *s)
{
unsigned long v = getauxval (t);
printf ("%s: %lu (0x%lx)\n", s, v, v);
if (v == 0)
missing++;
}
static void
check_eq (unsigned long t, const char *s, unsigned long want)
{
unsigned long v = getauxval (t);
printf ("%s: %lu want: %lu\n", s, v, want);
if (v != want)
mismatch++;
}
#define NZ(x) check_nonzero (x, #x)
#define EQ(x, want) check_eq (x, #x, want)
static int
do_test (void)
{
/* These auxv entries should be non-zero on Linux. */
NZ (AT_PHDR);
NZ (AT_PHENT);
NZ (AT_PHNUM);
NZ (AT_PAGESZ);
NZ (AT_ENTRY);
NZ (AT_CLKTCK);
NZ (AT_RANDOM);
NZ (AT_EXECFN);
if (missing)
FAIL_EXIT1 ("Found %d missing auxv entries.\n", missing);
/* Check against syscalls. */
EQ (AT_UID, getuid ());
EQ (AT_EUID, geteuid ());
EQ (AT_GID, getgid ());
EQ (AT_EGID, getegid ());
if (mismatch)
FAIL_EXIT1 ("Found %d mismatching auxv entries.\n", mismatch);
return 0;
}
#include <support/test-driver.c>