From: Yury Norov ynorov@caviumnetworks.com
maillist inclusion category: feature bugzilla: 46790 CVE: NA
Reference: https://github.com/norov/linux/commits/ilp32-5.2
--------------------------------
As we support more than one compat formats, it looks more reasonable to not use fs/compat_binfmt.c. Custom binfmt_elf32.c allows to move aarch32 specific definitions there and make code more maintainable and readable.
Signed-off-by: Yury Norov ynorov@caviumnetworks.com Signed-off-by: Yury Norov ynorov@marvell.com Signed-off-by: Xiongfeng Wang wangxiongfeng2@huawei.com Acked-by: Xie XiuQi xiexiuqi@huawei.com Signed-off-by: Chen Jun chenjun102@huawei.com
Conflicts: arch/arm64/kernel/binfmt_elf32.c
Signed-off-by: Chen Jiahao chenjiahao16@huawei.com --- arch/arm64/include/asm/elf.h | 22 ++++++---------------- arch/arm64/include/asm/hwcap.h | 2 -- arch/arm64/kernel/Makefile | 2 +- arch/arm64/kernel/binfmt_elf32.c | 27 +++++++++++++++++++++++++++ arch/arm64/kernel/process.c | 2 +- 5 files changed, 35 insertions(+), 20 deletions(-) create mode 100644 arch/arm64/kernel/binfmt_elf32.c
diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h index 2f7b8f1f8a34..de3ad90894ec 100644 --- a/arch/arm64/include/asm/elf.h +++ b/arch/arm64/include/asm/elf.h @@ -206,7 +206,9 @@ extern int arch_setup_additional_pages(struct linux_binprm *bprm,
/* PIE load location for compat arm. Must match ARM ELF_ET_DYN_BASE. */ #define COMPAT_ELF_ET_DYN_BASE 0x000400000UL +#endif /*CONFIG_COMPAT */
+#ifdef CONFIG_AARCH32_EL0 /* AArch32 registers. */ #define COMPAT_ELF_NGREG 18 typedef unsigned int compat_elf_greg_t; @@ -215,18 +217,8 @@ typedef compat_elf_greg_t compat_elf_gregset_t[COMPAT_ELF_NGREG]; /* AArch32 EABI. */ #define EF_ARM_EABI_MASK 0xff000000 int compat_elf_check_arch(const struct elf32_hdr *); -#define compat_elf_check_arch compat_elf_check_arch #define compat_start_thread compat_start_thread -/* - * Unlike the native SET_PERSONALITY macro, the compat version maintains - * READ_IMPLIES_EXEC across an execve() since this is the behaviour on - * arch/arm/. - */ -#define COMPAT_SET_PERSONALITY(ex) \ -({ \ - clear_thread_flag(TIF_32BIT_AARCH64); \ - set_thread_flag(TIF_32BIT); \ - }) + #ifdef CONFIG_COMPAT_VDSO #define COMPAT_ARCH_DLINFO \ do { \ @@ -242,12 +234,10 @@ do { \ #else #define COMPAT_ARCH_DLINFO #endif -extern int aarch32_setup_additional_pages(struct linux_binprm *bprm, - int uses_interp); -#define compat_arch_setup_additional_pages \ - aarch32_setup_additional_pages
-#endif /* CONFIG_COMPAT */ +extern int aarch32_setup_additional_pages(struct linux_binprm *bprm, + int uses_interp); +#endif /* CONFIG_AARCH32_EL0 */
struct arch_elf_state { int flags; diff --git a/arch/arm64/include/asm/hwcap.h b/arch/arm64/include/asm/hwcap.h index ceb8ed0c349a..844be1bc0e54 100644 --- a/arch/arm64/include/asm/hwcap.h +++ b/arch/arm64/include/asm/hwcap.h @@ -146,8 +146,6 @@ #define ELF_HWCAP2 cpu_get_elf_hwcap2()
#ifdef CONFIG_AARCH32_EL0 -#define COMPAT_ELF_HWCAP (compat_elf_hwcap) -#define COMPAT_ELF_HWCAP2 (compat_elf_hwcap2) extern unsigned int compat_elf_hwcap, compat_elf_hwcap2; #endif
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile index 32c2a129be25..811ba27a2bbb 100644 --- a/arch/arm64/kernel/Makefile +++ b/arch/arm64/kernel/Makefile @@ -36,7 +36,7 @@ obj-y := debug-monitors.o entry.o irq.o fpsimd.o \ syscall.o proton-pack.o idreg-override.o idle.o \ patching.o
-obj-$(CONFIG_AARCH32_EL0) += sys32.o signal32.o \ +obj-$(CONFIG_AARCH32_EL0) += binfmt_elf32.o sys32.o signal32.o \ sys_compat.o obj-$(CONFIG_AARCH32_EL0) += sigreturn32.o obj-$(CONFIG_COMPAT_ALIGNMENT_FIXUPS) += compat_alignment.o diff --git a/arch/arm64/kernel/binfmt_elf32.c b/arch/arm64/kernel/binfmt_elf32.c new file mode 100644 index 000000000000..e839a8753144 --- /dev/null +++ b/arch/arm64/kernel/binfmt_elf32.c @@ -0,0 +1,27 @@ +// SPDX-License-Identifier: GPL-2.0 + +/* + * Support for AArch32 Linux ELF binaries. + */ + +/* AArch32 EABI. */ +#define compat_start_thread compat_start_thread +/* + * Unlike the native SET_PERSONALITY macro, the compat version inherits + * READ_IMPLIES_EXEC across a fork() since this is the behaviour on + * arch/arm/. + */ +#define COMPAT_SET_PERSONALITY(ex) \ +({ \ + clear_thread_flag(TIF_32BIT_AARCH64); \ + set_thread_flag(TIF_32BIT); \ +}) + +#define COMPAT_ARCH_DLINFO +#define COMPAT_ELF_HWCAP (compat_elf_hwcap) +#define COMPAT_ELF_HWCAP2 (compat_elf_hwcap2) + +#define compat_arch_setup_additional_pages \ + aarch32_setup_additional_pages + +#include "../../../fs/compat_binfmt_elf.c" diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c index cf7a1f7807d3..82f2754ed4b5 100644 --- a/arch/arm64/kernel/process.c +++ b/arch/arm64/kernel/process.c @@ -597,7 +597,7 @@ unsigned long arch_align_stack(unsigned long sp) return sp & ~0xf; }
-#ifdef CONFIG_COMPAT +#ifdef CONFIG_AARCH32_EL0 int compat_elf_check_arch(const struct elf32_hdr *hdr) { if (!system_supports_32bit_el0())