aboutsummaryrefslogtreecommitdiff
path: root/sysdeps
diff options
context:
space:
mode:
authorFlorian Weimer <fweimer@redhat.com>2021-02-25 12:10:57 +0100
committerFlorian Weimer <fweimer@redhat.com>2021-02-25 12:13:02 +0100
commit035c012e32c11e84d64905efaf55e74f704d3668 (patch)
tree7b08a9e9cbd8e4dd2e420cd6b7c204aeb5d61ccc /sysdeps
parenta79328c745219dcb395070cdcd3be065a8347f24 (diff)
downloadglibc-035c012e32c11e84d64905efaf55e74f704d3668.tar.xz
glibc-035c012e32c11e84d64905efaf55e74f704d3668.zip
Reduce the statically linked startup code [BZ #23323]
It turns out the startup code in csu/elf-init.c has a perfect pair of ROP gadgets (see Marco-Gisbert and Ripoll-Ripoll, "return-to-csu: A New Method to Bypass 64-bit Linux ASLR"). These functions are not needed in dynamically-linked binaries because DT_INIT/DT_INIT_ARRAY are already processed by the dynamic linker. However, the dynamic linker skipped the main program for some reason. For maximum backwards compatibility, this is not changed, and instead, the main map is consulted from __libc_start_main if the init function argument is a NULL pointer. For statically linked binaries, the old approach based on linker symbols is still used because there is nothing else available. A new symbol version __libc_start_main@@GLIBC_2.34 is introduced because new binaries running on an old libc would not run their ELF constructors, leading to difficult-to-debug issues.
Diffstat (limited to 'sysdeps')
-rw-r--r--sysdeps/aarch64/start.S14
-rw-r--r--sysdeps/alpha/start.S5
-rw-r--r--sysdeps/arc/start.S7
-rw-r--r--sysdeps/arm/start.S22
-rw-r--r--sysdeps/csky/abiv2/start.S17
-rw-r--r--sysdeps/generic/ldsodefs.h6
-rw-r--r--sysdeps/hppa/dl-lookupcfg.h2
-rw-r--r--sysdeps/hppa/start.S26
-rw-r--r--sysdeps/i386/start.S14
-rw-r--r--sysdeps/ia64/dl-lookupcfg.h2
-rw-r--r--sysdeps/ia64/start.S9
-rw-r--r--sysdeps/m68k/start.S13
-rw-r--r--sysdeps/mach/hurd/i386/libc.abilist1
-rw-r--r--sysdeps/microblaze/start.S8
-rw-r--r--sysdeps/mips/start.S18
-rw-r--r--sysdeps/nios2/start.S17
-rw-r--r--sysdeps/powerpc/powerpc32/start.S4
-rw-r--r--sysdeps/powerpc/powerpc64/start.S4
-rw-r--r--sysdeps/riscv/start.S4
-rw-r--r--sysdeps/s390/s390-32/start.S10
-rw-r--r--sysdeps/s390/s390-64/start.S4
-rw-r--r--sysdeps/sh/start.S9
-rw-r--r--sysdeps/sparc/sparc32/start.S12
-rw-r--r--sysdeps/sparc/sparc64/start.S12
-rw-r--r--sysdeps/unix/sysv/linux/aarch64/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/alpha/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/arc/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/arm/be/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/arm/le/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/csky/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/hppa/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/i386/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/ia64/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/m68k/coldfire/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/m68k/m680x0/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/microblaze/be/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/microblaze/le/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/mips/mips32/fpu/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/mips/mips32/nofpu/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/mips/mips64/n32/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/mips/mips64/n64/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/nios2/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/libc-start.c13
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc32/fpu/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc32/nofpu/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc64/be/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/powerpc/powerpc64/le/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/riscv/rv32/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/riscv/rv64/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/s390/s390-32/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/s390/s390-64/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/sh/be/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/sh/le/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc32/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/sparc/sparc64/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/x86_64/64/libc.abilist1
-rw-r--r--sysdeps/unix/sysv/linux/x86_64/x32/libc.abilist1
-rw-r--r--sysdeps/x86_64/start.S12
58 files changed, 115 insertions, 182 deletions
diff --git a/sysdeps/aarch64/start.S b/sysdeps/aarch64/start.S
index 3761cbd7ee..417da8802b 100644
--- a/sysdeps/aarch64/start.S
+++ b/sysdeps/aarch64/start.S
@@ -63,26 +63,16 @@ ENTRY(_start)
# ifdef SHARED
adrp x0, :got:main
ldr PTR_REG (0), [x0, #:got_lo12:main]
-
- adrp x3, :got:__libc_csu_init
- ldr PTR_REG (3), [x3, #:got_lo12:__libc_csu_init]
-
- adrp x4, :got:__libc_csu_fini
- ldr PTR_REG (4), [x4, #:got_lo12:__libc_csu_fini]
# else
adrp x0, __wrap_main
add x0, x0, :lo12:__wrap_main
- adrp x3, __libc_csu_init
- add x3, x3, :lo12:__libc_csu_init
- adrp x4, __libc_csu_fini
- add x4, x4, :lo12:__libc_csu_fini
# endif
#else
/* Set up the other arguments in registers */
MOVL (0, main)
- MOVL (3, __libc_csu_init)
- MOVL (4, __libc_csu_fini)
#endif
+ mov x3, #0 /* Used to be init. */
+ mov x4, #0 /* Used to be fini. */
/* __libc_start_main (main, argc, argv, init, fini, rtld_fini,
stack_end) */
diff --git a/sysdeps/alpha/start.S b/sysdeps/alpha/start.S
index f3eb2029e1..65dcd4d392 100644
--- a/sysdeps/alpha/start.S
+++ b/sysdeps/alpha/start.S
@@ -55,9 +55,8 @@ _start:
ldl a1, 16(sp) /* get argc */
lda a2, 24(sp) /* get argv */
- /* Load address of our own entry points to .fini and .init. */
- lda a3, __libc_csu_init
- lda a4, __libc_csu_fini
+ mov $r31, a3 /* Used to be init. */
+ mov $r31, a4 /* Used to be fini. */
/* Store address of the shared library termination function. */
mov v0, a5
diff --git a/sysdeps/arc/start.S b/sysdeps/arc/start.S
index dbec87e6bb..5302a57cab 100644
--- a/sysdeps/arc/start.S
+++ b/sysdeps/arc/start.S
@@ -49,15 +49,14 @@ ENTRY (ENTRY_POINT)
/* __libc_start_main (main, argc, argv, init, fini, rtld_fini, stack_end). */
+ mov_s r3, 0 /* Used to be init. */
+ mov r4, 0 /* Used to be fini. */
+
#ifdef SHARED
ld r0, [pcl, @main@gotpc]
- ld r3, [pcl, @__libc_csu_init@gotpc]
- ld r4, [pcl, @__libc_csu_fini@gotpc]
bl __libc_start_main@plt
#else
mov_s r0, main
- mov_s r3, __libc_csu_init
- mov r4, __libc_csu_fini
bl __libc_start_main
#endif
diff --git a/sysdeps/arm/start.S b/sysdeps/arm/start.S
index 30f69e1b07..9b56bc0cca 100644
--- a/sysdeps/arm/start.S
+++ b/sysdeps/arm/start.S
@@ -94,30 +94,20 @@ _start:
adr a4, .L_GOT
add sl, sl, a4
- ldr ip, .L_GOT+4 /* __libc_csu_fini */
- ldr ip, [sl, ip]
+ mov a4, #0 /* Used to be init. */
+ push { a4 } /* Used to be fini. */
- push { ip } /* Push __libc_csu_fini */
-
- ldr a4, .L_GOT+8 /* __libc_csu_init */
- ldr a4, [sl, a4]
-
- ldr a1, .L_GOT+12 /* main */
+ ldr a1, .L_GOT+4 /* main */
ldr a1, [sl, a1]
/* __libc_start_main (main, argc, argv, init, fini, rtld_fini, stack_end) */
/* Let the libc call main and exit with its return code. */
bl __libc_start_main(PLT)
#else
- /* Fetch address of __libc_csu_fini */
- ldr ip, =__libc_csu_fini
-
- /* Push __libc_csu_fini */
- push { ip }
- /* Set up the other arguments in registers */
+ mov a4, #0 /* Used to init. */
+ push { a4 } /* Used to fini. */
ldr a1, =main
- ldr a4, =__libc_csu_init
/* __libc_start_main (main, argc, argv, init, fini, rtld_fini, stack_end) */
/* Let the libc call main and exit with its return code. */
@@ -131,8 +121,6 @@ _start:
.align 2
.L_GOT:
.word _GLOBAL_OFFSET_TABLE_ - .L_GOT
- .word __libc_csu_fini(GOT)
- .word __libc_csu_init(GOT)
.word main(GOT)
#endif
diff --git a/sysdeps/csky/abiv2/start.S b/sysdeps/csky/abiv2/start.S
index d65e37e61b..a565cfa87b 100644
--- a/sysdeps/csky/abiv2/start.S
+++ b/sysdeps/csky/abiv2/start.S
@@ -66,13 +66,9 @@ _start:
.Lgetpc:
lrw gb, .Lgetpc@GOTPC
addu gb, t0
- lrw a3, __libc_csu_fini@GOT
- ldr.w a3, (gb, a3 << 0)
- stw a3, (sp, 0)
- lrw a3, __libc_csu_init@GOT
- addu a3, gb
- ldw a3, (a3, 0)
+ movi a3, 0 /* Used to be init. */
+ stw a3, (sp, 0) /* Used to be fini. */
lrw t0, main@GOT
addu t0, gb
@@ -85,14 +81,9 @@ _start:
ldr.w t1, (gb, t1 << 0)
jsr t1
#else
- /* Fetch address of __libc_csu_fini. */
- lrw a0, __libc_csu_fini
- /* Push __libc_csu_fini */
- stw a0, (sp, 0)
-
- /* Set up the other arguments in registers. */
+ movi a3, 0 /* Used to be init. */
+ stw a3, (sp, 0) /* Used to be fini. */
lrw a0, main
- lrw a3, __libc_csu_init
/* Let the libc call main and exit with its return code. */
jsri __libc_start_main
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
index 9720a4e446..ea3f7a69d0 100644
--- a/sysdeps/generic/ldsodefs.h
+++ b/sysdeps/generic/ldsodefs.h
@@ -93,6 +93,10 @@ typedef struct link_map *lookup_t;
: (__glibc_unlikely ((ref)->st_shndx == SHN_ABS) ? 0 \
: LOOKUP_VALUE_ADDRESS (map, map_set)) + (ref)->st_value)
+/* Type of a constructor function, in DT_INIT, DT_INIT_ARRAY,
+ DT_PREINIT_ARRAY. */
+typedef void (*dl_init_t) (int, char **, char **);
+
/* On some architectures a pointer to a function is not just a pointer
to the actual code of the function but rather an architecture
specific descriptor. */
@@ -101,7 +105,7 @@ typedef struct link_map *lookup_t;
(void *) SYMBOL_ADDRESS (map, ref, false)
# define DL_LOOKUP_ADDRESS(addr) ((ElfW(Addr)) (addr))
# define DL_CALL_DT_INIT(map, start, argc, argv, env) \
- ((init_t) (start)) (argc, argv, env)
+ ((dl_init_t) (start)) (argc, argv, env)
# define DL_CALL_DT_FINI(map, start) ((fini_t) (start)) ()
#endif
diff --git a/sysdeps/hppa/dl-lookupcfg.h b/sysdeps/hppa/dl-lookupcfg.h
index 29d994bfc2..a9a927f26c 100644
--- a/sysdeps/hppa/dl-lookupcfg.h
+++ b/sysdeps/hppa/dl-lookupcfg.h
@@ -56,7 +56,7 @@ void attribute_hidden _dl_unmap (struct link_map *map);
{ \
ElfW(Addr) addr; \
DL_DT_FUNCTION_ADDRESS(map, start, , addr) \
- init_t init = (init_t) addr; \
+ dl_init_t init = (dl_init_t) addr; \
init (argc, argv, env); \
}
diff --git a/sysdeps/hppa/start.S b/sysdeps/hppa/start.S
index 2fe73c9aae..4a1877f8e8 100644
--- a/sysdeps/hppa/start.S
+++ b/sysdeps/hppa/start.S
@@ -36,8 +36,6 @@
.import main, code
.import $global$, data
.import __libc_start_main, code
- .import __libc_csu_fini, code
- .import __libc_csu_init, code
/* Have the linker create plabel words so we get PLABEL32
relocs and not 21/14. The use of 21/14 relocs is only
@@ -52,10 +50,6 @@
.word P%main
.Lp__libc_start_main:
.word P%__libc_start_main
-.Lp__libc_csu_fini:
- .word P%__libc_csu_fini
-.Lp__libc_csu_init:
- .word P%__libc_csu_init
.text
.align 4
@@ -77,8 +71,8 @@ _start:
1. r26 - Application main
2. r25 - argc
3. r24 - argv
- 4. r23 - __libc_csu_init
- 5. sp-52 - __libc_csu_fini
+ 4. r23 - init (unused)
+ 5. sp-52 - fini (unused)
6. sp-56 - rtld_fini
7. sp-60 - stackend */
@@ -108,14 +102,6 @@ _start:
addil LT'.Lpmain, %r19
ldw RT'.Lpmain(%r1), %r26
ldw 0(%r26),%r26
- /* void (*init) (void) (4th argument) */
- addil LT'.Lp__libc_csu_init, %r19
- ldw RT'.Lp__libc_csu_init(%r1), %r23
- ldw 0(%r23), %r23