aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorWill Deacon <will.deacon@arm.com>2013-07-25 06:44:48 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2013-07-26 07:02:10 -0400
commitacfdd4b1f7590d02e9bae3b73bdbbc4a31b05d38 (patch)
tree59864db2010f58b32a9b48d5a3cecc58b184a390 /arch
parentbdae73cd374e28db544fdd9b77de689a36e3c129 (diff)
ARM: 7791/1: a.out: remove partial a.out support
a.out support on ARM requires that argc, argv and envp are passed in r0-r2 respectively, which requires hacking load_aout_binary to prevent argc being clobbered by the return code. Whilst mainline kernels do set the registers up in start_thread, the aout loader has never carried the hack in mainline. Initialising the registers in this way actually goes against the libc expectations for ELF binaries, where argc, argv and envp are passed on the stack, with r0 being used to hold a pointer to an exit function for cleaning up after the dynamic linker if required. If the pointer is NULL, then it is ignored. When execing an ELF binary, Linux currently zeroes r0, then sets it to argc and then finally clobbers it with the return value of the execve syscall, so we actually end up with: r0 = 0 stack[0] = argc r1 = stack[1] = argv r2 = stack[2] = envp libc treats r1 and r2 as undefined. The clobbering of r0 by sys_execve works for user-spawned threads, but when executing an ELF binary from a kernel thread (via call_usermodehelper), the execve is performed on the ret_from_fork path, which restores r0 from the saved pt_regs, resulting in argc being presented to the C library. This has horrible consequences when the application exits, since we have an exit function registered using argc, resulting in a jump to hyperspace. This patch solves the problem by removing the partial a.out support from arch/arm/ altogether. Cc: <stable@vger.kernel.org> Cc: Ashish Sangwan <ashishsangwan2@gmail.com> Signed-off-by: Will Deacon <will.deacon@arm.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/Kconfig1
-rw-r--r--arch/arm/include/asm/a.out-core.h45
-rw-r--r--arch/arm/include/asm/processor.h4
-rw-r--r--arch/arm/include/uapi/asm/Kbuild1
-rw-r--r--arch/arm/include/uapi/asm/a.out.h34
5 files changed, 0 insertions, 85 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index ba412e02ec0c..82f069829ac0 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -20,7 +20,6 @@ config ARM
20 select GENERIC_STRNCPY_FROM_USER 20 select GENERIC_STRNCPY_FROM_USER
21 select GENERIC_STRNLEN_USER 21 select GENERIC_STRNLEN_USER
22 select HARDIRQS_SW_RESEND 22 select HARDIRQS_SW_RESEND
23 select HAVE_AOUT
24 select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL 23 select HAVE_ARCH_JUMP_LABEL if !XIP_KERNEL
25 select HAVE_ARCH_KGDB 24 select HAVE_ARCH_KGDB
26 select HAVE_ARCH_SECCOMP_FILTER 25 select HAVE_ARCH_SECCOMP_FILTER
diff --git a/arch/arm/include/asm/a.out-core.h b/arch/arm/include/asm/a.out-core.h
deleted file mode 100644
index 92f10cb5c70c..000000000000
--- a/arch/arm/include/asm/a.out-core.h
+++ /dev/null
@@ -1,45 +0,0 @@
1/* a.out coredump register dumper
2 *
3 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public Licence
8 * as published by the Free Software Foundation; either version
9 * 2 of the Licence, or (at your option) any later version.
10 */
11
12#ifndef _ASM_A_OUT_CORE_H
13#define _ASM_A_OUT_CORE_H
14
15#ifdef __KERNEL__
16
17#include <linux/user.h>
18#include <linux/elfcore.h>
19
20/*
21 * fill in the user structure for an a.out core dump
22 */
23static inline void aout_dump_thread(struct pt_regs *regs, struct user *dump)
24{
25 struct task_struct *tsk = current;
26
27 dump->magic = CMAGIC;
28 dump->start_code = tsk->mm->start_code;
29 dump->start_stack = regs->ARM_sp & ~(PAGE_SIZE - 1);
30
31 dump->u_tsize = (tsk->mm->end_code - tsk->mm->start_code) >> PAGE_SHIFT;
32 dump->u_dsize = (tsk->mm->brk - tsk->mm->start_data + PAGE_SIZE - 1) >> PAGE_SHIFT;
33 dump->u_ssize = 0;
34
35 memset(dump->u_debugreg, 0, sizeof(dump->u_debugreg));
36
37 if (dump->start_stack < 0x04000000)
38 dump->u_ssize = (0x04000000 - dump->start_stack) >> PAGE_SHIFT;
39
40 dump->regs = *regs;
41 dump->u_fpvalid = dump_fpu (regs, &dump->u_fp);
42}
43
44#endif /* __KERNEL__ */
45#endif /* _ASM_A_OUT_CORE_H */
diff --git a/arch/arm/include/asm/processor.h b/arch/arm/include/asm/processor.h
index 06e7d509eaac..413f3876341c 100644
--- a/arch/arm/include/asm/processor.h
+++ b/arch/arm/include/asm/processor.h
@@ -54,7 +54,6 @@ struct thread_struct {
54 54
55#define start_thread(regs,pc,sp) \ 55#define start_thread(regs,pc,sp) \
56({ \ 56({ \
57 unsigned long *stack = (unsigned long *)sp; \
58 memset(regs->uregs, 0, sizeof(regs->uregs)); \ 57 memset(regs->uregs, 0, sizeof(regs->uregs)); \
59 if (current->personality & ADDR_LIMIT_32BIT) \ 58 if (current->personality & ADDR_LIMIT_32BIT) \
60 regs->ARM_cpsr = USR_MODE; \ 59 regs->ARM_cpsr = USR_MODE; \
@@ -65,9 +64,6 @@ struct thread_struct {
65 regs->ARM_cpsr |= PSR_ENDSTATE; \ 64 regs->ARM_cpsr |= PSR_ENDSTATE; \
66 regs->ARM_pc = pc & ~1; /* pc */ \ 65 regs->ARM_pc = pc & ~1; /* pc */ \
67 regs->ARM_sp = sp; /* sp */ \ 66 regs->ARM_sp = sp; /* sp */ \
68 regs->ARM_r2 = stack[2]; /* r2 (envp) */ \
69 regs->ARM_r1 = stack[1]; /* r1 (argv) */ \
70 regs->ARM_r0 = stack[0]; /* r0 (argc) */ \
71 nommu_start_thread(regs); \ 67 nommu_start_thread(regs); \
72}) 68})
73 69
diff --git a/arch/arm/include/uapi/asm/Kbuild b/arch/arm/include/uapi/asm/Kbuild
index 47bcb2d254af..18d76fd5a2af 100644
--- a/arch/arm/include/uapi/asm/Kbuild
+++ b/arch/arm/include/uapi/asm/Kbuild
@@ -1,7 +1,6 @@
1# UAPI Header export list 1# UAPI Header export list
2include include/uapi/asm-generic/Kbuild.asm 2include include/uapi/asm-generic/Kbuild.asm
3 3
4header-y += a.out.h
5header-y += byteorder.h 4header-y += byteorder.h
6header-y += fcntl.h 5header-y += fcntl.h
7header-y += hwcap.h 6header-y += hwcap.h
diff --git a/arch/arm/include/uapi/asm/a.out.h b/arch/arm/include/uapi/asm/a.out.h
deleted file mode 100644
index 083894b2e3bc..000000000000
--- a/arch/arm/include/uapi/asm/a.out.h
+++ /dev/null
@@ -1,34 +0,0 @@
1#ifndef __ARM_A_OUT_H__
2#define __ARM_A_OUT_H__
3
4#include <linux/personality.h>
5#include <linux/types.h>
6
7struct exec
8{
9 __u32 a_info; /* Use macros N_MAGIC, etc for access */
10 __u32 a_text; /* length of text, in bytes */
11 __u32 a_data; /* length of data, in bytes */
12 __u32 a_bss; /* length of uninitialized data area for file, in bytes */
13 __u32 a_syms; /* length of symbol table data in file, in bytes */
14 __u32 a_entry; /* start address */
15 __u32 a_trsize; /* length of relocation info for text, in bytes */
16 __u32 a_drsize; /* length of relocation info for data, in bytes */
17};
18
19/*
20 * This is always the same
21 */
22#define N_TXTADDR(a) (0x00008000)
23
24#define N_TRSIZE(a) ((a).a_trsize)
25#define N_DRSIZE(a) ((a).a_drsize)
26#define N_SYMSIZE(a) ((a).a_syms)
27
28#define M_ARM 103
29
30#ifndef LIBRARY_START_TEXT
31#define LIBRARY_START_TEXT (0x00c00000)
32#endif
33
34#endif /* __A_OUT_GNU_H__ */