^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) #include <linux/personality.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) #include <linux/binfmts.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/elf.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/elf-fdpic.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <asm/system_info.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) int elf_check_arch(const struct elf32_hdr *x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) unsigned int eflags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) /* Make sure it's an ARM executable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) if (x->e_machine != EM_ARM)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) /* Make sure the entry address is reasonable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) if (x->e_entry & 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) if (!(elf_hwcap & HWCAP_THUMB))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) } else if (x->e_entry & 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) eflags = x->e_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) if ((eflags & EF_ARM_EABI_MASK) == EF_ARM_EABI_UNKNOWN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) unsigned int flt_fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) /* APCS26 is only allowed if the CPU supports it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) if ((eflags & EF_ARM_APCS_26) && !(elf_hwcap & HWCAP_26BIT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) flt_fmt = eflags & (EF_ARM_VFP_FLOAT | EF_ARM_SOFT_FLOAT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) /* VFP requires the supporting code */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) if (flt_fmt == EF_ARM_VFP_FLOAT && !(elf_hwcap & HWCAP_VFP))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) EXPORT_SYMBOL(elf_check_arch);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) void elf_set_personality(const struct elf32_hdr *x)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) unsigned int eflags = x->e_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) unsigned int personality = current->personality & ~PER_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * We only support Linux ELF executables, so always set the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * personality to LINUX.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) personality |= PER_LINUX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) * APCS-26 is only valid for OABI executables
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) if ((eflags & EF_ARM_EABI_MASK) == EF_ARM_EABI_UNKNOWN &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) (eflags & EF_ARM_APCS_26))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) personality &= ~ADDR_LIMIT_32BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) personality |= ADDR_LIMIT_32BIT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) set_personality(personality);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) * Since the FPA coprocessor uses CP1 and CP2, and iWMMXt uses CP0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) * and CP1, we only enable access to the iWMMXt coprocessor if the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) * binary is EABI or softfloat (and thus, guaranteed not to use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) * FPA instructions.)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) if (elf_hwcap & HWCAP_IWMMXT &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) eflags & (EF_ARM_EABI_MASK | EF_ARM_SOFT_FLOAT)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) set_thread_flag(TIF_USING_IWMMXT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) clear_thread_flag(TIF_USING_IWMMXT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) EXPORT_SYMBOL(elf_set_personality);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) * An executable for which elf_read_implies_exec() returns TRUE will
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) * have the READ_IMPLIES_EXEC personality flag set automatically.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) * The decision process for determining the results are:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) * CPU: | lacks NX* | has NX |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) * ELF: | | |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) * ---------------------|------------|------------|
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) * missing PT_GNU_STACK | exec-all | exec-all |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) * PT_GNU_STACK == RWX | exec-all | exec-stack |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) * PT_GNU_STACK == RW | exec-all | exec-none |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) * exec-all : all PROT_READ user mappings are executable, except when
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) * backed by files on a noexec-filesystem.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) * exec-none : only PROT_EXEC user mappings are executable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) * exec-stack: only the stack and PROT_EXEC user mappings are executable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) * *this column has no architectural effect: NX markings are ignored by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) * hardware, but may have behavioral effects when "wants X" collides with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) * "cannot be X" constraints in memory permission flags, as in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) * https://lkml.kernel.org/r/20190418055759.GA3155@mellanox.com
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) int arm_elf_read_implies_exec(int executable_stack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) if (executable_stack == EXSTACK_DEFAULT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) if (cpu_architecture() < CPU_ARCH_ARMv6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) EXPORT_SYMBOL(arm_elf_read_implies_exec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) #if defined(CONFIG_MMU) && defined(CONFIG_BINFMT_ELF_FDPIC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) void elf_fdpic_arch_lay_out_mm(struct elf_fdpic_params *exec_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) struct elf_fdpic_params *interp_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) unsigned long *start_stack,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) unsigned long *start_brk)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) elf_set_personality(&exec_params->hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) exec_params->load_addr = 0x8000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) interp_params->load_addr = ELF_ET_DYN_BASE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) *start_stack = TASK_SIZE - SZ_16M;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) if ((exec_params->flags & ELF_FDPIC_FLAG_ARRANGEMENT) == ELF_FDPIC_FLAG_INDEPENDENT) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) exec_params->flags &= ~ELF_FDPIC_FLAG_ARRANGEMENT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) exec_params->flags |= ELF_FDPIC_FLAG_CONSTDISP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) #endif