mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-04 01:24:12 +08:00
90776dd1c4
It seems that LLVM's linker does not correctly handle variable assignments involving section positions that are updated during the SECTIONS parsing. Commitaa69fb62be
("arm64/efi: Mark __efistub_stext_offset as an absolute symbol explicitly") ran into this too, but found a different workaround. However, this was not enough, as other variables were also miscalculated which manifested as boot failures under UEFI where __efistub__end was not taking the correct _end value (they should be the same): $ ld.lld -EL -maarch64elf --no-undefined -X -shared \ -Bsymbolic -z notext -z norelro --no-apply-dynamic-relocs \ -o vmlinux.lld -T poc.lds --whole-archive vmlinux.o && \ readelf -Ws vmlinux.lld | egrep '\b(__efistub_|)_end\b' 368272: ffff000002218000 0 NOTYPE LOCAL HIDDEN 38 __efistub__end 368322: ffff000012318000 0 NOTYPE GLOBAL DEFAULT 38 _end $ aarch64-linux-gnu-ld.bfd -EL -maarch64elf --no-undefined -X -shared \ -Bsymbolic -z notext -z norelro --no-apply-dynamic-relocs \ -o vmlinux.bfd -T poc.lds --whole-archive vmlinux.o && \ readelf -Ws vmlinux.bfd | egrep '\b(__efistub_|)_end\b' 338124: ffff000012318000 0 NOTYPE LOCAL DEFAULT ABS __efistub__end 383812: ffff000012318000 0 NOTYPE GLOBAL DEFAULT 15325 _end To work around this, all of the __efistub_-prefixed variable assignments need to be moved after the linker script's SECTIONS entry. As it turns out, this also solves the problem fixed in commitaa69fb62be
, so those changes are reverted here. Link: https://github.com/ClangBuiltLinux/linux/issues/634 Link: https://bugs.llvm.org/show_bug.cgi?id=42990 Acked-by: Ard Biesheuvel <ard.biesheuvel@linaro.org> Signed-off-by: Kees Cook <keescook@chromium.org> Signed-off-by: Will Deacon <will@kernel.org>
52 lines
1.5 KiB
C
52 lines
1.5 KiB
C
/* SPDX-License-Identifier: GPL-2.0-only */
|
|
/*
|
|
* Linker script variables to be set after section resolution, as
|
|
* ld.lld does not like variables assigned before SECTIONS is processed.
|
|
*/
|
|
#ifndef __ARM64_KERNEL_IMAGE_VARS_H
|
|
#define __ARM64_KERNEL_IMAGE_VARS_H
|
|
|
|
#ifndef LINKER_SCRIPT
|
|
#error This file should only be included in vmlinux.lds.S
|
|
#endif
|
|
|
|
#ifdef CONFIG_EFI
|
|
|
|
__efistub_stext_offset = stext - _text;
|
|
|
|
/*
|
|
* The EFI stub has its own symbol namespace prefixed by __efistub_, to
|
|
* isolate it from the kernel proper. The following symbols are legally
|
|
* accessed by the stub, so provide some aliases to make them accessible.
|
|
* Only include data symbols here, or text symbols of functions that are
|
|
* guaranteed to be safe when executed at another offset than they were
|
|
* linked at. The routines below are all implemented in assembler in a
|
|
* position independent manner
|
|
*/
|
|
__efistub_memcmp = __pi_memcmp;
|
|
__efistub_memchr = __pi_memchr;
|
|
__efistub_memcpy = __pi_memcpy;
|
|
__efistub_memmove = __pi_memmove;
|
|
__efistub_memset = __pi_memset;
|
|
__efistub_strlen = __pi_strlen;
|
|
__efistub_strnlen = __pi_strnlen;
|
|
__efistub_strcmp = __pi_strcmp;
|
|
__efistub_strncmp = __pi_strncmp;
|
|
__efistub_strrchr = __pi_strrchr;
|
|
__efistub___flush_dcache_area = __pi___flush_dcache_area;
|
|
|
|
#ifdef CONFIG_KASAN
|
|
__efistub___memcpy = __pi_memcpy;
|
|
__efistub___memmove = __pi_memmove;
|
|
__efistub___memset = __pi_memset;
|
|
#endif
|
|
|
|
__efistub__text = _text;
|
|
__efistub__end = _end;
|
|
__efistub__edata = _edata;
|
|
__efistub_screen_info = screen_info;
|
|
|
|
#endif
|
|
|
|
#endif /* __ARM64_KERNEL_IMAGE_VARS_H */
|