Hi,
This series is a collection of various cleanups for compat64:
- Patch 1 makes use of the new in_compat64_syscall() helper introduced by Zach in his BPF series to unify the way we check whether we are handling a compat64 syscall. - Patch 2-4 aim to restore compat_binfmt_elf as close to its original shape as possible, by using most of the existing definitions for compat64 as well as compat32. - Patch 5 converts remaining uses of #ifdef CONFIG_COMPAT to CONFIG_COMPAT32 when the corresponding code is specific to AArch32. - Patch 6 fixes the number of ASLR bits in compat64, which should be the same as in native and not the AArch32 value.
Aside from making things a little clearer and removing some unused code in compat64, patch 4 and 5 bring minor functional improvements. See the commit messages for details.
Review branch:
https://git.morello-project.org/kbrodsky-arm/linux/-/commits/morello/compat6...
Cheers, Kevin
Kevin Brodsky (6): treewide: Use in_compat64_syscall() for compat64 checks arm64: Only define COMPAT_ELF_HWCAP* in compat32 arm64/elf: Only define compat_elf_read_implies_exec in compat32 fs/compat_binfmt_elf: Align compat64 with compat32 arm64: Disable remaining 32-bit handling in compat64 arm64: Kconfig: Use native mmap_rnd_bits in compat64
arch/arm64/Kconfig | 2 +- arch/arm64/include/asm/arch_timer.h | 2 +- arch/arm64/include/asm/elf.h | 50 ++++++++++----------- arch/arm64/include/asm/fpsimd.h | 2 +- arch/arm64/include/asm/hwcap.h | 4 +- arch/arm64/include/asm/mmu.h | 2 +- arch/arm64/include/asm/processor.h | 8 ++-- arch/arm64/include/asm/ptrace.h | 2 +- arch/arm64/include/asm/seccomp.h | 2 +- arch/arm64/include/asm/unistd.h | 6 ++- arch/arm64/kernel/cpufeature.c | 14 +++--- arch/arm64/kernel/cpuinfo.c | 8 ++-- arch/arm64/kernel/entry-common.c | 6 +-- arch/arm64/kernel/traps.c | 4 +- arch/arm64/mm/init.c | 2 +- drivers/mmc/core/block.c | 11 ++--- fs/compat_binfmt_elf.c | 68 +++++++++++++---------------- include/linux/elfcore-compat.h | 7 +++ io_uring/io_uring.c | 2 +- io_uring/uring_cmd.c | 2 +- kernel/futex/syscalls.c | 2 +- net/ipv4/tcp.c | 18 +++----- 22 files changed, 109 insertions(+), 115 deletions(-)
"arch: add compat helpers specific to 64-bit" introduced the generic helper in_compat64_syscall() to check if the syscall was made in compat64 specifically. We have a number of equivalent helpers scattered across the tree, as well as open-coded checks. Replace them with calls to in_compat64_syscall().
Signed-off-by: Kevin Brodsky kevin.brodsky@arm.com --- drivers/mmc/core/block.c | 11 +++-------- io_uring/io_uring.c | 2 +- io_uring/uring_cmd.c | 2 +- kernel/futex/syscalls.c | 2 +- net/ipv4/tcp.c | 18 +++++++----------- 5 files changed, 13 insertions(+), 22 deletions(-)
diff --git a/drivers/mmc/core/block.c b/drivers/mmc/core/block.c index 0422137a3bdd..14297236a60e 100644 --- a/drivers/mmc/core/block.c +++ b/drivers/mmc/core/block.c @@ -101,11 +101,6 @@ struct mmc_blk_busy_data { u32 status; };
-static inline bool in_compat64(void) -{ - return IS_ENABLED(CONFIG_COMPAT64) && in_compat_syscall(); -} - struct compat_mmc_ioc_cmd { int write_flag; int is_acmd; @@ -463,7 +458,7 @@ static int get_mmc_ioc_cmd_from_compat64(struct mmc_ioc_cmd *native_cmd,
static int copy_mmc_ioc_cmd_from_user(struct mmc_ioc_cmd *to, void * __user src) { - if (in_compat64()) + if (in_compat64_syscall()) return get_mmc_ioc_cmd_from_compat64(to, src);
if (copy_from_user_with_ptr(to, src, sizeof(*to))) @@ -519,7 +514,7 @@ static int mmc_blk_ioctl_copy_to_user(struct mmc_ioc_cmd __user *ic_ptr, { struct mmc_ioc_cmd *ic = &idata->ic;
- __u32 __user *response_uptr = in_compat64() ? + __u32 __user *response_uptr = in_compat64_syscall() ? &((struct compat_mmc_ioc_cmd __user *)ic_ptr)->response[0] : &ic_ptr->response[0];
@@ -756,7 +751,7 @@ static inline struct mmc_ioc_cmd __user *get_ith_mmc_ioc_cmd_uptr( struct mmc_ioc_multi_cmd __user *user, unsigned int i) { - if (in_compat64()) + if (in_compat64_syscall()) return (struct mmc_ioc_cmd __user *)&((struct compat_mmc_ioc_multi_cmd __user *)user)->cmds[i]; return &(user->cmds[i]); } diff --git a/io_uring/io_uring.c b/io_uring/io_uring.c index e77a1460e55c..e1b12f8f7007 100644 --- a/io_uring/io_uring.c +++ b/io_uring/io_uring.c @@ -251,7 +251,7 @@ static int get_compat64_io_uring_params(struct io_uring_params *params, static int copy_io_uring_params_from_user(struct io_uring_params *params, const void __user *src) { - if (IS_ENABLED(CONFIG_COMPAT64) && in_compat_syscall()) + if (in_compat64_syscall()) return get_compat64_io_uring_params(params, src); if (copy_from_user_with_ptr(params, src, sizeof(*params))) return -EFAULT; diff --git a/io_uring/uring_cmd.c b/io_uring/uring_cmd.c index db184905c20d..a471a0971c70 100644 --- a/io_uring/uring_cmd.c +++ b/io_uring/uring_cmd.c @@ -216,7 +216,7 @@ EXPORT_SYMBOL_GPL(io_uring_cmd_import_fixed);
static inline void __user *sqe_get_optval(const struct io_uring_sqe *sqe) { - if (IS_ENABLED(CONFIG_COMPAT64) && in_compat_syscall()) { + if (in_compat64_syscall()) { const __u64 *val = io_uring_sqe_cmd(sqe); return compat_ptr(READ_ONCE(*val)); } else { diff --git a/kernel/futex/syscalls.c b/kernel/futex/syscalls.c index ea49ee054a74..4840d3195977 100644 --- a/kernel/futex/syscalls.c +++ b/kernel/futex/syscalls.c @@ -194,7 +194,7 @@ static int copy_futex_waitv_from_user(struct futex_waitv *aux, const struct futex_waitv __user *uwaitv, unsigned int i) { - if (IS_ENABLED(CONFIG_COMPAT64) && in_compat_syscall()) { + if (in_compat64_syscall()) { const struct compat_futex_waitv __user *compat_uwaitv = (const struct compat_futex_waitv __user *)uwaitv; struct compat_futex_waitv compat_aux; diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index 4e001d8d4cd6..7b8870f86210 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -1818,11 +1818,6 @@ struct compat_tcp_zerocopy_receive { __u32 reserved; };
-static inline bool in_compat64(void) -{ - return IS_ENABLED(CONFIG_COMPAT64) && in_compat_syscall(); -} - static int get_compat64_tcp_zerocopy_receive(struct tcp_zerocopy_receive *zc, sockptr_t src, size_t size) { @@ -1849,7 +1844,7 @@ static int get_compat64_tcp_zerocopy_receive(struct tcp_zerocopy_receive *zc, static int copy_tcp_zerocopy_receive_from_sockptr(struct tcp_zerocopy_receive *zc, sockptr_t src, size_t size) { - if (in_compat64()) + if (in_compat64_syscall()) return get_compat64_tcp_zerocopy_receive(zc, src, size); if (copy_from_sockptr_with_ptr(zc, src, size)) return -EFAULT; @@ -1882,7 +1877,7 @@ static int copy_tcp_zerocopy_receive_to_sockptr(sockptr_t dst, struct tcp_zerocopy_receive *zc, size_t size) { - if (in_compat64()) + if (in_compat64_syscall()) return set_compat64_tcp_zerocopy_receive(dst, zc, size); if (copy_to_sockptr_with_ptr(dst, zc, size)) return -EFAULT; @@ -4341,14 +4336,15 @@ int do_tcp_getsockopt(struct sock *sk, int level, } #ifdef CONFIG_MMU #define offsetofend_tcp_zerocopy_receive(member) \ - (in_compat64() ? offsetofend(struct compat_tcp_zerocopy_receive, member) \ - : offsetofend(struct tcp_zerocopy_receive, member)) + (in_compat64_syscall() ? offsetofend(struct compat_tcp_zerocopy_receive, member) \ + : offsetofend(struct tcp_zerocopy_receive, member)) case TCP_ZEROCOPY_RECEIVE: { struct scm_timestamping_internal tss; struct tcp_zerocopy_receive zc = {}; int err; - size_t zc_size = in_compat64() ? sizeof(struct compat_tcp_zerocopy_receive) - : sizeof(struct tcp_zerocopy_receive); + size_t zc_size = in_compat64_syscall() ? + sizeof(struct compat_tcp_zerocopy_receive) : + sizeof(struct tcp_zerocopy_receive);
if (copy_from_sockptr(&len, optlen, sizeof(int))) return -EFAULT;
COMPAT_ELF_HWCAP* are only relevant for AArch32. We don't need them when compat is 64-bit.
This should be a non-functional change, as COMPAT_ELF_HWCAP* are not currently considered in compat64, and cpuinfo.c checks the PER_LINUX32 personality, which is not set in compat64.
Signed-off-by: Kevin Brodsky kevin.brodsky@arm.com --- arch/arm64/include/asm/arch_timer.h | 2 +- arch/arm64/include/asm/hwcap.h | 4 ++-- arch/arm64/kernel/cpufeature.c | 14 +++++++------- arch/arm64/kernel/cpuinfo.c | 8 ++++---- 4 files changed, 14 insertions(+), 14 deletions(-)
diff --git a/arch/arm64/include/asm/arch_timer.h b/arch/arm64/include/asm/arch_timer.h index 934c658ee947..147e11e5adb6 100644 --- a/arch/arm64/include/asm/arch_timer.h +++ b/arch/arm64/include/asm/arch_timer.h @@ -217,7 +217,7 @@ static inline int arch_timer_arch_init(void) static inline void arch_timer_set_evtstrm_feature(void) { cpu_set_named_feature(EVTSTRM); -#ifdef CONFIG_COMPAT +#ifdef CONFIG_COMPAT32 compat_elf_hwcap |= COMPAT_HWCAP_EVTSTRM; #endif } diff --git a/arch/arm64/include/asm/hwcap.h b/arch/arm64/include/asm/hwcap.h index 38cffeb3227a..c2e0f28f2982 100644 --- a/arch/arm64/include/asm/hwcap.h +++ b/arch/arm64/include/asm/hwcap.h @@ -151,7 +151,7 @@ #define ELF_HWCAP cpu_get_elf_hwcap() #define ELF_HWCAP2 cpu_get_elf_hwcap2()
-#ifdef CONFIG_COMPAT +#ifdef CONFIG_COMPAT32 #define COMPAT_ELF_HWCAP (compat_elf_hwcap) #define COMPAT_ELF_HWCAP2 (compat_elf_hwcap2) extern unsigned int compat_elf_hwcap, compat_elf_hwcap2; @@ -159,7 +159,7 @@ extern unsigned int compat_elf_hwcap, compat_elf_hwcap2;
enum { CAP_HWCAP = 1, -#ifdef CONFIG_COMPAT +#ifdef CONFIG_COMPAT32 CAP_COMPAT_HWCAP, CAP_COMPAT_HWCAP2, #endif diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c index 2002813f91ca..abbee1da1c2f 100644 --- a/arch/arm64/kernel/cpufeature.c +++ b/arch/arm64/kernel/cpufeature.c @@ -96,7 +96,7 @@ /* Kernel representation of AT_HWCAP and AT_HWCAP2 */ static DECLARE_BITMAP(elf_hwcap, MAX_CPU_FEATURES) __read_mostly;
-#ifdef CONFIG_COMPAT +#ifdef CONFIG_COMPAT32 #define COMPAT_ELF_HWCAP_DEFAULT \ (COMPAT_HWCAP_HALF|COMPAT_HWCAP_THUMB|\ COMPAT_HWCAP_FAST_MULT|COMPAT_HWCAP_EDSP|\ @@ -2221,10 +2221,10 @@ static void user_feature_fixup(void)
static void elf_hwcap_fixup(void) { -#ifdef CONFIG_COMPAT +#ifdef CONFIG_COMPAT32 if (cpus_have_cap(ARM64_WORKAROUND_1742098)) compat_elf_hwcap2 &= ~COMPAT_HWCAP2_AES; -#endif /* CONFIG_COMPAT */ +#endif /* CONFIG_COMPAT32 */ }
#ifdef CONFIG_KVM @@ -2934,7 +2934,7 @@ static const struct arm64_cpu_capabilities arm64_elf_hwcaps[] = { {}, };
-#ifdef CONFIG_COMPAT +#ifdef CONFIG_COMPAT32 static bool compat_has_neon(const struct arm64_cpu_capabilities *cap, int scope) { /* @@ -2957,7 +2957,7 @@ static bool compat_has_neon(const struct arm64_cpu_capabilities *cap, int scope) #endif
static const struct arm64_cpu_capabilities compat_elf_hwcaps[] = { -#ifdef CONFIG_COMPAT +#ifdef CONFIG_COMPAT32 HWCAP_CAP_MATCH(compat_has_neon, CAP_COMPAT_HWCAP, COMPAT_HWCAP_NEON), HWCAP_CAP(MVFR1_EL1, SIMDFMAC, IMP, CAP_COMPAT_HWCAP, COMPAT_HWCAP_VFPv4), /* Arm v8 mandates MVFR0.FPDP == {0, 2}. So, piggy back on this for the presence of VFP support */ @@ -2986,7 +2986,7 @@ static void cap_set_elf_hwcap(const struct arm64_cpu_capabilities *cap) case CAP_HWCAP: cpu_set_feature(cap->hwcap); break; -#ifdef CONFIG_COMPAT +#ifdef CONFIG_COMPAT32 case CAP_COMPAT_HWCAP: compat_elf_hwcap |= (u32)cap->hwcap; break; @@ -3009,7 +3009,7 @@ static bool cpus_have_elf_hwcap(const struct arm64_cpu_capabilities *cap) case CAP_HWCAP: rc = cpu_have_feature(cap->hwcap); break; -#ifdef CONFIG_COMPAT +#ifdef CONFIG_COMPAT32 case CAP_COMPAT_HWCAP: rc = (compat_elf_hwcap & (u32)cap->hwcap) != 0; break; diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c index 4e2159aa5cb3..060aef1baaca 100644 --- a/arch/arm64/kernel/cpuinfo.c +++ b/arch/arm64/kernel/cpuinfo.c @@ -133,7 +133,7 @@ static const char *const hwcap_str[] = { [KERNEL_HWCAP_MORELLO] = "morello", };
-#ifdef CONFIG_COMPAT +#ifdef CONFIG_COMPAT32 #define COMPAT_KERNEL_HWCAP(x) const_ilog2(COMPAT_HWCAP_ ## x) static const char *const compat_hwcap_str[] = { [COMPAT_KERNEL_HWCAP(SWP)] = "swp", @@ -176,7 +176,7 @@ static const char *const compat_hwcap2_str[] = { [COMPAT_KERNEL_HWCAP2(SB)] = "sb", [COMPAT_KERNEL_HWCAP2(SSBS)] = "ssbs", }; -#endif /* CONFIG_COMPAT */ +#endif /* CONFIG_COMPAT32 */
static int c_show(struct seq_file *m, void *v) { @@ -209,7 +209,7 @@ static int c_show(struct seq_file *m, void *v) */ seq_puts(m, "Features\t:"); if (compat) { -#ifdef CONFIG_COMPAT +#ifdef CONFIG_COMPAT32 for (j = 0; j < ARRAY_SIZE(compat_hwcap_str); j++) { if (compat_elf_hwcap & (1 << j)) { /* @@ -226,7 +226,7 @@ static int c_show(struct seq_file *m, void *v) for (j = 0; j < ARRAY_SIZE(compat_hwcap2_str); j++) if (compat_elf_hwcap2 & (1 << j)) seq_printf(m, " %s", compat_hwcap2_str[j]); -#endif /* CONFIG_COMPAT */ +#endif /* CONFIG_COMPAT32 */ } else { for (j = 0; j < ARRAY_SIZE(hwcap_str); j++) if (cpu_have_feature(j))
READ_IMPLIES_EXEC is only used on AArch32. Just use the standard elf_read_implies_exec() macro in compat64.
Non-functional change as compat_elf_read_implies_exec is not currently considered in compat64.
Signed-off-by: Kevin Brodsky kevin.brodsky@arm.com --- arch/arm64/include/asm/elf.h | 46 ++++++++++++++++++------------------ 1 file changed, 23 insertions(+), 23 deletions(-)
diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h index 9f5157840205..4c556ac15e04 100644 --- a/arch/arm64/include/asm/elf.h +++ b/arch/arm64/include/asm/elf.h @@ -102,29 +102,6 @@ #define elf_check_arch(x) ((x)->e_machine == EM_AARCH64) #endif
-/* - * An executable for which elf_read_implies_exec() returns TRUE will - * have the READ_IMPLIES_EXEC personality flag set automatically. - * - * The decision process for determining the results are: - * - * CPU*: | arm32 | arm64 | - * ELF: | | | - * ---------------------|------------|------------| - * missing PT_GNU_STACK | exec-all | exec-none | - * PT_GNU_STACK == RWX | exec-stack | exec-stack | - * PT_GNU_STACK == RW | exec-none | exec-none | - * - * exec-all : all PROT_READ user mappings are executable, except when - * backed by files on a noexec-filesystem. - * exec-none : only PROT_EXEC user mappings are executable. - * exec-stack: only the stack and PROT_EXEC user mappings are executable. - * - * *all arm64 CPUs support NX, so there is no "lacks NX" column. - * - */ -#define compat_elf_read_implies_exec(ex, stk) (stk == EXSTACK_DEFAULT) - #define CORE_DUMP_USE_REGSET #define ELF_EXEC_PAGESIZE PAGE_SIZE
@@ -294,6 +271,29 @@ extern int aarch32_setup_additional_pages(struct linux_binprm *bprm, #define compat_arch_setup_additional_pages \ aarch32_setup_additional_pages
+/* + * An executable for which elf_read_implies_exec() returns TRUE will + * have the READ_IMPLIES_EXEC personality flag set automatically. + * + * The decision process for determining the results are: + * + * CPU*: | arm32 | arm64 | + * ELF: | | | + * ---------------------|------------|------------| + * missing PT_GNU_STACK | exec-all | exec-none | + * PT_GNU_STACK == RWX | exec-stack | exec-stack | + * PT_GNU_STACK == RW | exec-none | exec-none | + * + * exec-all : all PROT_READ user mappings are executable, except when + * backed by files on a noexec-filesystem. + * exec-none : only PROT_EXEC user mappings are executable. + * exec-stack: only the stack and PROT_EXEC user mappings are executable. + * + * *all arm64 CPUs support NX, so there is no "lacks NX" column. + * + */ +#define compat_elf_read_implies_exec(ex, stk) (stk == EXSTACK_DEFAULT) + #endif /* !CONFIG_COMPAT64 */
#endif /* CONFIG_COMPAT */
"arm64/binfmt_elf: Disable compat32 definitions for compat64" introduced a special path for compat64 in compat_binfmt_elf, avoiding most existing definitions. Subsequent commits partially reverted this by making more definitions common to compat32 and compat64. This commit completes this process by returning compat_binfmt_elf to its original state, except where definitions are strictly 32-bit specific (small CONFIG_COMPAT32 block at the top of the file).
This is made possible by recent commits that ensure that compat_elf_read_implies_exec and COMPAT_ELF_HWCAP2* are not defined in compat64. Additionally, struct compat_elf_prstatus_common in elfcore-compat.h is amended to use a 64-bit time format in compat64.
This change is mostly non-functional, with the following exceptions:
* copy_siginfo_to_external() was incorrectly used in compat64. copy_siginfo_to_external32() is now used instead, performing the appropriate layout conversion (despite its name, it is suitable to compat64 too).
* Symbols like elf_format are now renamed to e.g. compat_elf_format in compat64 too, easing debugging.
Signed-off-by: Kevin Brodsky kevin.brodsky@arm.com --- fs/compat_binfmt_elf.c | 68 +++++++++++++++------------------- include/linux/elfcore-compat.h | 7 ++++ 2 files changed, 37 insertions(+), 38 deletions(-)
diff --git a/fs/compat_binfmt_elf.c b/fs/compat_binfmt_elf.c index b3204b54af36..6f108d3e1278 100644 --- a/fs/compat_binfmt_elf.c +++ b/fs/compat_binfmt_elf.c @@ -14,16 +14,7 @@ * functions used in binfmt_elf.c to compat versions. */
-#ifdef CONFIG_COMPAT32 #include <linux/elfcore-compat.h> -#else -/* - * TODO [PCuABI] - The header linux/elfcore-compat.h needs some changes for - * complete compat64 support so for time being include minimum definitions - * from linux/elf.h. - */ -#include <linux/elf.h> -#endif /* CONFIG_COMPAT32 */ #include <linux/time.h>
#define ELF_COMPAT 1 @@ -45,6 +36,7 @@ #define elf_stack_put_user(val, ptr) put_user((elf_addr_t)(user_uintptr_t)(val), (ptr))
#ifdef CONFIG_COMPAT32 + /* * Rename the basic ELF layout types to refer to the 32-bit class of files. */ @@ -64,6 +56,11 @@ #define elf_addr_t Elf32_Addr #define ELF_GNU_PROPERTY_ALIGN ELF32_GNU_PROPERTY_ALIGN
+#undef ns_to_kernel_old_timeval +#define ns_to_kernel_old_timeval ns_to_old_timeval32 + +#endif /* CONFIG_COMPAT32 */ + /* * Some data types as stored in coredump. */ @@ -79,15 +76,15 @@ #define elf_prstatus_common compat_elf_prstatus_common #define elf_prpsinfo compat_elf_prpsinfo
-#undef ns_to_kernel_old_timeval -#define ns_to_kernel_old_timeval ns_to_old_timeval32 - /* * To use this file, asm/elf.h must define compat_elf_check_arch. * The other following macros can be defined if the compat versions * differ from the native ones, or omitted when they match. */
+#undef elf_check_arch +#define elf_check_arch compat_elf_check_arch + #ifdef COMPAT_ELF_PLATFORM #undef ELF_PLATFORM #define ELF_PLATFORM COMPAT_ELF_PLATFORM @@ -103,6 +100,11 @@ #define ELF_HWCAP2 COMPAT_ELF_HWCAP2 #endif
+#ifdef COMPAT_ARCH_DLINFO +#undef ARCH_DLINFO +#define ARCH_DLINFO COMPAT_ARCH_DLINFO +#endif + #ifdef COMPAT_ELF_ET_DYN_BASE #undef ELF_ET_DYN_BASE #define ELF_ET_DYN_BASE COMPAT_ELF_ET_DYN_BASE @@ -113,32 +115,6 @@ #define ELF_PLAT_INIT COMPAT_ELF_PLAT_INIT #endif
-#ifdef compat_elf_read_implies_exec -#undef elf_read_implies_exec -#define elf_read_implies_exec compat_elf_read_implies_exec -#endif - -/* - * Rename a few of the symbols that binfmt_elf.c will define. - * These are all local so the names don't really matter, but it - * might make some debugging less confusing not to duplicate them. - */ -#define elf_format compat_elf_format -#define init_elf_binfmt init_compat_elf_binfmt -#define exit_elf_binfmt exit_compat_elf_binfmt -#define binfmt_elf_test_cases compat_binfmt_elf_test_cases -#define binfmt_elf_test_suite compat_binfmt_elf_test_suite - -#endif /* CONFIG_COMPAT32 */ - -#undef elf_check_arch -#define elf_check_arch compat_elf_check_arch - -#ifdef COMPAT_ARCH_DLINFO -#undef ARCH_DLINFO -#define ARCH_DLINFO COMPAT_ARCH_DLINFO -#endif - #ifdef COMPAT_SET_PERSONALITY #undef SET_PERSONALITY #define SET_PERSONALITY COMPAT_SET_PERSONALITY @@ -170,6 +146,22 @@ #define ARCH_SETUP_ADDITIONAL_PAGES COMPAT_ARCH_SETUP_ADDITIONAL_PAGES #endif
+#ifdef compat_elf_read_implies_exec +#undef elf_read_implies_exec +#define elf_read_implies_exec compat_elf_read_implies_exec +#endif + +/* + * Rename a few of the symbols that binfmt_elf.c will define. + * These are all local so the names don't really matter, but it + * might make some debugging less confusing not to duplicate them. + */ +#define elf_format compat_elf_format +#define init_elf_binfmt init_compat_elf_binfmt +#define exit_elf_binfmt exit_compat_elf_binfmt +#define binfmt_elf_test_cases compat_binfmt_elf_test_cases +#define binfmt_elf_test_suite compat_binfmt_elf_test_suite + /* * We share all the actual code with the native (64-bit) version. */ diff --git a/include/linux/elfcore-compat.h b/include/linux/elfcore-compat.h index 54feb64e9b5d..db9029d69bd3 100644 --- a/include/linux/elfcore-compat.h +++ b/include/linux/elfcore-compat.h @@ -27,10 +27,17 @@ struct compat_elf_prstatus_common compat_pid_t pr_ppid; compat_pid_t pr_pgrp; compat_pid_t pr_sid; +#ifdef CONFIG_COMPAT64 + struct __kernel_old_timeval pr_utime; + struct __kernel_old_timeval pr_stime; + struct __kernel_old_timeval pr_cutime; + struct __kernel_old_timeval pr_cstime; +#else struct old_timeval32 pr_utime; struct old_timeval32 pr_stime; struct old_timeval32 pr_cutime; struct old_timeval32 pr_cstime; +#endif };
struct compat_elf_prpsinfo
Most #ifdef CONFIG_COMPAT in arch/arm64 really are about 32-bit specifically. Many have been converted already, but a few remain: take care of those.
This change is mostly non-functional, with the following exception:
* arch_parse_elf_property() was incorrectly skipped in compat64. This had no impact on Morello as the only allocated property if for BTI, which is not implemented on Morello.
Signed-off-by: Kevin Brodsky kevin.brodsky@arm.com --- arch/arm64/include/asm/elf.h | 4 ++-- arch/arm64/include/asm/fpsimd.h | 2 +- arch/arm64/include/asm/mmu.h | 2 +- arch/arm64/include/asm/processor.h | 8 ++++---- arch/arm64/include/asm/ptrace.h | 2 +- arch/arm64/include/asm/seccomp.h | 2 +- arch/arm64/include/asm/unistd.h | 6 +++++- arch/arm64/kernel/entry-common.c | 6 +++--- arch/arm64/kernel/traps.c | 4 ++-- arch/arm64/mm/init.c | 2 +- 10 files changed, 21 insertions(+), 17 deletions(-)
diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h index 4c556ac15e04..b54070e80867 100644 --- a/arch/arm64/include/asm/elf.h +++ b/arch/arm64/include/asm/elf.h @@ -186,7 +186,7 @@ extern int purecap_setup_additional_pages(struct linux_binprm *bprm, #endif /* CONFIG_CHERI_PURECAP_UABI */
/* 1GB of VA */ -#ifdef CONFIG_COMPAT +#ifdef CONFIG_COMPAT32 #define STACK_RND_MASK (test_thread_flag(TIF_32BIT) ? \ 0x7ff >> (PAGE_SHIFT - 12) : \ 0x3ffff >> (PAGE_SHIFT - 12)) @@ -313,7 +313,7 @@ static inline int arch_parse_elf_property(u32 type, const void *data, struct arch_elf_state *arch) { /* No known properties for AArch32 yet */ - if (IS_ENABLED(CONFIG_COMPAT) && compat) + if (IS_ENABLED(CONFIG_COMPAT32) && compat) return 0;
if (type == GNU_PROPERTY_AARCH64_FEATURE_1_AND) { diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h index 50e5f25d3024..62a5e4688883 100644 --- a/arch/arm64/include/asm/fpsimd.h +++ b/arch/arm64/include/asm/fpsimd.h @@ -21,7 +21,7 @@ #include <linux/stddef.h> #include <linux/types.h>
-#ifdef CONFIG_COMPAT +#ifdef CONFIG_COMPAT32 /* Masks for extracting the FPSR and FPCR from the FPSCR */ #define VFP_FPSCR_STAT_MASK 0xf800009f #define VFP_FPSCR_CTRL_MASK 0x07f79f00 diff --git a/arch/arm64/include/asm/mmu.h b/arch/arm64/include/asm/mmu.h index 2fcf51231d6e..12a7889f0a37 100644 --- a/arch/arm64/include/asm/mmu.h +++ b/arch/arm64/include/asm/mmu.h @@ -19,7 +19,7 @@
typedef struct { atomic64_t id; -#ifdef CONFIG_COMPAT +#ifdef CONFIG_COMPAT32 void *sigpage; #endif refcount_t pinned; diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h index 472d4332715f..ab02589247f4 100644 --- a/arch/arm64/include/asm/processor.h +++ b/arch/arm64/include/asm/processor.h @@ -55,7 +55,7 @@ #define TASK_SIZE_64 (UL(1) << vabits_actual) #define TASK_SIZE_MAX (UL(1) << VA_BITS)
-#ifdef CONFIG_COMPAT +#ifdef CONFIG_COMPAT32 #if defined(CONFIG_ARM64_64K_PAGES) && defined(CONFIG_KUSER_HELPERS) /* * With CONFIG_ARM64_64K_PAGES enabled, the last page is occupied @@ -74,7 +74,7 @@ #else #define TASK_SIZE TASK_SIZE_64 #define DEFAULT_MAP_WINDOW DEFAULT_MAP_WINDOW_64 -#endif /* CONFIG_COMPAT */ +#endif /* CONFIG_COMPAT32 */
#ifdef CONFIG_ARM64_FORCE_52BIT #define STACK_TOP_MAX TASK_SIZE_64 @@ -84,13 +84,13 @@ #define TASK_UNMAPPED_BASE (PAGE_ALIGN(DEFAULT_MAP_WINDOW / 4)) #endif /* CONFIG_ARM64_FORCE_52BIT */
-#ifdef CONFIG_COMPAT +#ifdef CONFIG_COMPAT32 #define AARCH32_VECTORS_BASE 0xffff0000 #define STACK_TOP (test_thread_flag(TIF_32BIT) ? \ AARCH32_VECTORS_BASE : STACK_TOP_MAX) #else #define STACK_TOP STACK_TOP_MAX -#endif /* CONFIG_COMPAT */ +#endif /* CONFIG_COMPAT32 */
#ifndef CONFIG_ARM64_FORCE_52BIT #define arch_get_mmap_end(addr, len, flags) \ diff --git a/arch/arm64/include/asm/ptrace.h b/arch/arm64/include/asm/ptrace.h index 8746d88338d3..5d682f0ccd3f 100644 --- a/arch/arm64/include/asm/ptrace.h +++ b/arch/arm64/include/asm/ptrace.h @@ -225,7 +225,7 @@ static inline void forget_syscall(struct pt_regs *regs)
#define arch_has_single_step() (1)
-#ifdef CONFIG_COMPAT +#ifdef CONFIG_COMPAT32 #define compat_thumb_mode(regs) \ (((regs)->pstate & PSR_AA32_T_BIT)) #else diff --git a/arch/arm64/include/asm/seccomp.h b/arch/arm64/include/asm/seccomp.h index 65958a8f661c..4ef492fa0528 100644 --- a/arch/arm64/include/asm/seccomp.h +++ b/arch/arm64/include/asm/seccomp.h @@ -15,7 +15,7 @@ #define __NR_seccomp_write_32 __NR_compat_write #define __NR_seccomp_exit_32 __NR_compat_exit #define __NR_seccomp_sigreturn_32 __NR_compat_rt_sigreturn -#endif /* CONFIG_COMPAT */ +#endif /* CONFIG_COMPAT32 */
#include <asm-generic/seccomp.h>
diff --git a/arch/arm64/include/asm/unistd.h b/arch/arm64/include/asm/unistd.h index 531effca5f1f..12863ce079e4 100644 --- a/arch/arm64/include/asm/unistd.h +++ b/arch/arm64/include/asm/unistd.h @@ -2,7 +2,7 @@ /* * Copyright (C) 2012 ARM Ltd. */ -#ifdef CONFIG_COMPAT +#ifdef CONFIG_COMPAT32 #define __ARCH_WANT_COMPAT_STAT #define __ARCH_WANT_COMPAT_STAT64 #define __ARCH_WANT_SYS_GETHOSTNAME @@ -42,6 +42,10 @@ #define __NR_compat_syscalls 457 #endif
+#ifdef CONFIG_COMPAT64 +#define __NR_compat_syscalls __NR_syscalls +#endif + #define __ARCH_WANT_SYS_CLONE
#ifndef __COMPAT_SYSCALL_NR diff --git a/arch/arm64/kernel/entry-common.c b/arch/arm64/kernel/entry-common.c index 0fc94207e69a..63cab2184e11 100644 --- a/arch/arm64/kernel/entry-common.c +++ b/arch/arm64/kernel/entry-common.c @@ -801,7 +801,7 @@ asmlinkage void noinstr el0t_64_error_handler(struct pt_regs *regs) __el0_error_handler_common(regs); }
-#ifdef CONFIG_COMPAT +#ifdef CONFIG_COMPAT32 static void noinstr el0_cp15(struct pt_regs *regs, unsigned long esr) { enter_from_user_mode(regs); @@ -877,12 +877,12 @@ asmlinkage void noinstr el0t_32_error_handler(struct pt_regs *regs) { __el0_error_handler_common(regs); } -#else /* CONFIG_COMPAT */ +#else /* CONFIG_COMPAT32 */ UNHANDLED(el0t, 32, sync) UNHANDLED(el0t, 32, irq) UNHANDLED(el0t, 32, fiq) UNHANDLED(el0t, 32, error) -#endif /* CONFIG_COMPAT */ +#endif /* CONFIG_COMPAT32 */
#ifdef CONFIG_VMAP_STACK asmlinkage void noinstr __noreturn handle_bad_stack(struct pt_regs *regs) diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c index f2653f40e86d..5e9744ce727b 100644 --- a/arch/arm64/kernel/traps.c +++ b/arch/arm64/kernel/traps.c @@ -302,7 +302,7 @@ void arm64_notify_die(const char *str, struct pt_regs *regs, } }
-#ifdef CONFIG_COMPAT +#ifdef CONFIG_COMPAT32 #define PSTATE_IT_1_0_SHIFT 25 #define PSTATE_IT_1_0_MASK (0x3 << PSTATE_IT_1_0_SHIFT) #define PSTATE_IT_7_2_SHIFT 10 @@ -684,7 +684,7 @@ static const struct sys64_hook sys64_hooks[] = { {}, };
-#ifdef CONFIG_COMPAT +#ifdef CONFIG_COMPAT32 static bool cp15_cond_valid(unsigned long esr, struct pt_regs *regs) { int cond; diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c index 74c1db8ce271..c6c0b7df1986 100644 --- a/arch/arm64/mm/init.c +++ b/arch/arm64/mm/init.c @@ -390,7 +390,7 @@ void __init mem_init(void) * Check boundaries twice: Some fundamental inconsistencies can be * detected at build time already. */ -#ifdef CONFIG_COMPAT +#ifdef CONFIG_COMPAT32 BUILD_BUG_ON(TASK_SIZE_32 > DEFAULT_MAP_WINDOW_64); #endif
Hi,
On 12/28/23 19:23, Kevin Brodsky wrote:
Most #ifdef CONFIG_COMPAT in arch/arm64 really are about 32-bit specifically. Many have been converted already, but a few remain: take care of those.
This change is mostly non-functional, with the following exception:
- arch_parse_elf_property() was incorrectly skipped in compat64. This had no impact on Morello as the only allocated property if for BTI, which is not implemented on Morello.
Signed-off-by: Kevin Brodsky kevin.brodsky@arm.com
arch/arm64/include/asm/elf.h | 4 ++-- arch/arm64/include/asm/fpsimd.h | 2 +- arch/arm64/include/asm/mmu.h | 2 +- arch/arm64/include/asm/processor.h | 8 ++++---- arch/arm64/include/asm/ptrace.h | 2 +- arch/arm64/include/asm/seccomp.h | 2 +- arch/arm64/include/asm/unistd.h | 6 +++++- arch/arm64/kernel/entry-common.c | 6 +++--- arch/arm64/kernel/traps.c | 4 ++-- arch/arm64/mm/init.c | 2 +- 10 files changed, 21 insertions(+), 17 deletions(-)
I did a quick search of CONFIG_COMPAT. All the changes look fine to me and probably below code can also be included.
diff --git a/arch/arm64/kernel/syscall.c b/arch/arm64/kernel/syscall.c index 0feb55df863f..2116ee0bb7e2 100644 --- a/arch/arm64/kernel/syscall.c +++ b/arch/arm64/kernel/syscall.c @@ -204,7 +204,7 @@ void do_el0_svc(struct pt_regs *regs) el0_svc_common(regs, regs->regs[8], __NR_syscalls, table); }
-#ifdef CONFIG_COMPAT +#ifdef CONFIG_COMPAT32 void do_el0_svc_compat(struct pt_regs *regs) { el0_svc_common(regs, regs->regs[7], __NR_compat_syscalls,
Thanks, Amit
diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h index 4c556ac15e04..b54070e80867 100644 --- a/arch/arm64/include/asm/elf.h +++ b/arch/arm64/include/asm/elf.h @@ -186,7 +186,7 @@ extern int purecap_setup_additional_pages(struct linux_binprm *bprm, #endif /* CONFIG_CHERI_PURECAP_UABI */
On 10/01/2024 05:03, Amit Daniel Kachhap wrote:
I did a quick search of CONFIG_COMPAT. All the changes look fine to me and probably below code can also be included.
diff --git a/arch/arm64/kernel/syscall.c b/arch/arm64/kernel/syscall.c index 0feb55df863f..2116ee0bb7e2 100644 --- a/arch/arm64/kernel/syscall.c +++ b/arch/arm64/kernel/syscall.c @@ -204,7 +204,7 @@ void do_el0_svc(struct pt_regs *regs) el0_svc_common(regs, regs->regs[8], __NR_syscalls, table); }
-#ifdef CONFIG_COMPAT +#ifdef CONFIG_COMPAT32 void do_el0_svc_compat(struct pt_regs *regs) { el0_svc_common(regs, regs->regs[7], __NR_compat_syscalls,
Thanks for the review, and good catch! I didn't look carefully, I thought this was for compat in general, but in fact compat64 is handled in do_el0_svc(). Will change that #ifdef too.
Kevin
The ARCH_MMAP_RND_COMPAT_BITS* values are only appropriate for AArch32. For compat64, we do not need separate values, as the address space size is the same as in native.
This patch restores the number of ASLR bits to its appropriate value in compat64 by unselecting HAVE_ARCH_MMAP_RND_COMPAT_BITS, so that the native values are used in compat64 too.
Signed-off-by: Kevin Brodsky kevin.brodsky@arm.com --- arch/arm64/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 1c35447ebb87..83a5817afa7d 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -172,7 +172,7 @@ config ARM64 select HAVE_ARCH_KFENCE select HAVE_ARCH_KGDB select HAVE_ARCH_MMAP_RND_BITS - select HAVE_ARCH_MMAP_RND_COMPAT_BITS if COMPAT + select HAVE_ARCH_MMAP_RND_COMPAT_BITS if COMPAT32 select HAVE_ARCH_PREL32_RELOCATIONS select HAVE_ARCH_RANDOMIZE_KSTACK_OFFSET select HAVE_ARCH_SECCOMP_FILTER
On 28/12/2023 13:53, Kevin Brodsky wrote:
Hi,
This series is a collection of various cleanups for compat64:
- Patch 1 makes use of the new in_compat64_syscall() helper introduced by Zach in his BPF series to unify the way we check whether we are handling a compat64 syscall.
- Patch 2-4 aim to restore compat_binfmt_elf as close to its original shape as possible, by using most of the existing definitions for compat64 as well as compat32.
- Patch 5 converts remaining uses of #ifdef CONFIG_COMPAT to CONFIG_COMPAT32 when the corresponding code is specific to AArch32.
- Patch 6 fixes the number of ASLR bits in compat64, which should be the same as in native and not the AArch32 value.
Aside from making things a little clearer and removing some unused code in compat64, patch 4 and 5 bring minor functional improvements. See the commit messages for details.
Review branch:
https://git.morello-project.org/kbrodsky-arm/linux/-/commits/morello/compat6...
Cheers, Kevin
Kevin Brodsky (6): treewide: Use in_compat64_syscall() for compat64 checks arm64: Only define COMPAT_ELF_HWCAP* in compat32 arm64/elf: Only define compat_elf_read_implies_exec in compat32 fs/compat_binfmt_elf: Align compat64 with compat32 arm64: Disable remaining 32-bit handling in compat64 arm64: Kconfig: Use native mmap_rnd_bits in compat64
Applied on next, with the additional change suggested by Amit on patch 5.
Kevin
arch/arm64/Kconfig | 2 +- arch/arm64/include/asm/arch_timer.h | 2 +- arch/arm64/include/asm/elf.h | 50 ++++++++++----------- arch/arm64/include/asm/fpsimd.h | 2 +- arch/arm64/include/asm/hwcap.h | 4 +- arch/arm64/include/asm/mmu.h | 2 +- arch/arm64/include/asm/processor.h | 8 ++-- arch/arm64/include/asm/ptrace.h | 2 +- arch/arm64/include/asm/seccomp.h | 2 +- arch/arm64/include/asm/unistd.h | 6 ++- arch/arm64/kernel/cpufeature.c | 14 +++--- arch/arm64/kernel/cpuinfo.c | 8 ++-- arch/arm64/kernel/entry-common.c | 6 +-- arch/arm64/kernel/traps.c | 4 +- arch/arm64/mm/init.c | 2 +- drivers/mmc/core/block.c | 11 ++--- fs/compat_binfmt_elf.c | 68 +++++++++++++---------------- include/linux/elfcore-compat.h | 7 +++ io_uring/io_uring.c | 2 +- io_uring/uring_cmd.c | 2 +- kernel/futex/syscalls.c | 2 +- net/ipv4/tcp.c | 18 +++----- 22 files changed, 109 insertions(+), 115 deletions(-)
linux-morello@op-lists.linaro.org