Skip to content

Commit cea5589

Browse files
Jens RemusAlexander Gordeev
authored andcommitted
s390/boot: Do not adjust GOT entries for undef weak sym
Since commit 778666d ("s390: compile relocatable kernel without -fPIE") and commit 00cda11 ("s390: Compile kernel with -fPIC and link with -no-pie") the kernel on s390x may have a Global Offset Table (GOT) whose entries are adjusted for KASLR in kaslr_adjust_got(). The GOT may contain entries for undefined weak symbols that resolved to zero. That is the resulting GOT entry value is zero. Adjusting those entries unconditionally in kaslr_adjust_got() is wrong. Otherwise the following sample code would erroneously assume foo to be defined, due to the adjustment changing the zero-value to a non-zero one: extern int foo __attribute__((weak)); if (*foo) /* foo is defined [or undefined and erroneously adjusted] */ The vmlinux build at commit 00cda11 ("s390: Compile kernel with -fPIC and link with -no-pie") with defconfig actually had two GOT entries for the undefined weak symbols __start_BTF and __stop_BTF: $ objdump -tw vmlinux | grep -F "*UND*" 0000000000000000 w *UND* 0000000000000000 __stop_BTF 0000000000000000 w *UND* 0000000000000000 __start_BTF $ readelf -rw vmlinux | grep -E "R_390_GOTENT +0{16}" 000000345760 2776a0000001a R_390_GOTENT 0000000000000000 __stop_BTF + 2 000000345766 2d5480000001a R_390_GOTENT 0000000000000000 __start_BTF + 2 The s390-specific vmlinux linker script sets the section start to __START_KERNEL, which is currently defined as 0x100000 on s390x. Access to lowcore is performed via a pointer of 0 and not a symbol in a section starting at 0. The first 64K are reserved for the loader on s390x. Thus it is safe to assume that __START_KERNEL will never be 0. As a result there cannot be any defined symbols resolving to zero in the kernel. Note that the first three GOT entries are reserved for the dynamic loader on s390x. [1] In the kernel they are zero. Therefore no extra handling is required to skip these. Skip adjusting GOT entries with a value of zero in kaslr_adjust_got(). While at it update the comment when a GOT exists on s390x. Since commit 00cda11 ("s390: Compile kernel with -fPIC and link with -no-pie") it no longer only exists when compiling with Clang, but also with GCC. [1]: s390x ELF ABI, section "Global Offset Table", https://github.com/IBM/s390x-abi/releases Fixes: 778666d ("s390: compile relocatable kernel without -fPIE") Reviewed-by: Ilya Leoshkevich <[email protected]> Acked-by: Sumanth Korikkar <[email protected]> Acked-by: Alexander Gordeev <[email protected]> Signed-off-by: Jens Remus <[email protected]> Signed-off-by: Alexander Gordeev <[email protected]>
1 parent 6434b33 commit cea5589

File tree

1 file changed

+7
-4
lines changed

1 file changed

+7
-4
lines changed

arch/s390/boot/startup.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -170,11 +170,14 @@ static void kaslr_adjust_got(unsigned long offset)
170170
u64 *entry;
171171

172172
/*
173-
* Even without -fPIE, Clang still uses a global offset table for some
174-
* reason. Adjust the GOT entries.
173+
* Adjust GOT entries, except for ones for undefined weak symbols
174+
* that resolved to zero. This also skips the first three reserved
175+
* entries on s390x that are zero.
175176
*/
176-
for (entry = (u64 *)vmlinux.got_start; entry < (u64 *)vmlinux.got_end; entry++)
177-
*entry += offset - __START_KERNEL;
177+
for (entry = (u64 *)vmlinux.got_start; entry < (u64 *)vmlinux.got_end; entry++) {
178+
if (*entry)
179+
*entry += offset - __START_KERNEL;
180+
}
178181
}
179182

180183
/*

0 commit comments

Comments
 (0)