diff options
author | Catalin Marinas <catalin.marinas@arm.com> | 2007-07-11 06:29:39 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2007-07-12 11:20:52 -0400 |
commit | d1cbbd6b413510c6512f4f80ffd48db1a8dd554a (patch) | |
tree | fb3f908530cf2c4957aa45256214ed7d59557820 /include/asm-arm/ptrace.h | |
parent | f884b1cf578e079f01682514ae1ae64c74586602 (diff) |
[ARM] 4474/1: Do not check the PSR_F_BIT in valid_user_regs
When running Linux in non-secure mode (on ARM1176 for example),
depending on the CP15 secure configuration register, the CPSR.F bit
(6) might only be modified from the secure mode. However, the
valid_user_regs() function checks for this bit being cleared. With
commit a6c61e9d, a SIGSEGV is forced in handle_signal() if the user
registers are not considered valid.
The patch also ensures that the CPSR.A bit is cleared and the USR mode
is set if the CPU does not support the 26bit user mode.
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'include/asm-arm/ptrace.h')
-rw-r--r-- | include/asm-arm/ptrace.h | 12 |
1 files changed, 9 insertions, 3 deletions
diff --git a/include/asm-arm/ptrace.h b/include/asm-arm/ptrace.h index ff038b65f370..7aaa206cb54e 100644 --- a/include/asm-arm/ptrace.h +++ b/include/asm-arm/ptrace.h | |||
@@ -10,6 +10,8 @@ | |||
10 | #ifndef __ASM_ARM_PTRACE_H | 10 | #ifndef __ASM_ARM_PTRACE_H |
11 | #define __ASM_ARM_PTRACE_H | 11 | #define __ASM_ARM_PTRACE_H |
12 | 12 | ||
13 | #include <asm/hwcap.h> | ||
14 | |||
13 | #define PTRACE_GETREGS 12 | 15 | #define PTRACE_GETREGS 12 |
14 | #define PTRACE_SETREGS 13 | 16 | #define PTRACE_SETREGS 13 |
15 | #define PTRACE_GETFPREGS 14 | 17 | #define PTRACE_GETFPREGS 14 |
@@ -45,6 +47,7 @@ | |||
45 | #define PSR_T_BIT 0x00000020 | 47 | #define PSR_T_BIT 0x00000020 |
46 | #define PSR_F_BIT 0x00000040 | 48 | #define PSR_F_BIT 0x00000040 |
47 | #define PSR_I_BIT 0x00000080 | 49 | #define PSR_I_BIT 0x00000080 |
50 | #define PSR_A_BIT 0x00000100 | ||
48 | #define PSR_J_BIT 0x01000000 | 51 | #define PSR_J_BIT 0x01000000 |
49 | #define PSR_Q_BIT 0x08000000 | 52 | #define PSR_Q_BIT 0x08000000 |
50 | #define PSR_V_BIT 0x10000000 | 53 | #define PSR_V_BIT 0x10000000 |
@@ -121,14 +124,17 @@ struct pt_regs { | |||
121 | */ | 124 | */ |
122 | static inline int valid_user_regs(struct pt_regs *regs) | 125 | static inline int valid_user_regs(struct pt_regs *regs) |
123 | { | 126 | { |
124 | if (user_mode(regs) && | 127 | if (user_mode(regs) && (regs->ARM_cpsr & PSR_I_BIT) == 0) { |
125 | (regs->ARM_cpsr & (PSR_F_BIT|PSR_I_BIT)) == 0) | 128 | regs->ARM_cpsr &= ~(PSR_F_BIT | PSR_A_BIT); |
126 | return 1; | 129 | return 1; |
130 | } | ||
127 | 131 | ||
128 | /* | 132 | /* |
129 | * Force CPSR to something logical... | 133 | * Force CPSR to something logical... |
130 | */ | 134 | */ |
131 | regs->ARM_cpsr &= PSR_f | PSR_s | PSR_x | PSR_T_BIT | MODE32_BIT; | 135 | regs->ARM_cpsr &= PSR_f | PSR_s | (PSR_x & ~PSR_A_BIT) | PSR_T_BIT | MODE32_BIT; |
136 | if (!(elf_hwcap & HWCAP_26BIT)) | ||
137 | regs->ARM_cpsr |= USR_MODE; | ||
132 | 138 | ||
133 | return 0; | 139 | return 0; |
134 | } | 140 | } |