aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2010-08-13 18:33:46 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2010-08-15 17:04:24 -0400
commit41e2e8fd34fff909a0e40129f6ac4233ecfa67a9 (patch)
tree46dd3fe7a0a2ecb12325f4af96d2aedb3ff7835e /arch
parent21d93e2e29722d7832f61cc56d73fb953ee6578e (diff)
ARM: Tighten check for allowable CPSR values
Reviewed-by: Arve Hjønnevåg <arve@android.com> Acked-by: Dima Zavin <dima@android.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/include/asm/ptrace.h17
1 files changed, 13 insertions, 4 deletions
diff --git a/arch/arm/include/asm/ptrace.h b/arch/arm/include/asm/ptrace.h
index c974be8913a7..7ce15eb15f72 100644
--- a/arch/arm/include/asm/ptrace.h
+++ b/arch/arm/include/asm/ptrace.h
@@ -158,15 +158,24 @@ struct pt_regs {
158 */ 158 */
159static inline int valid_user_regs(struct pt_regs *regs) 159static inline int valid_user_regs(struct pt_regs *regs)
160{ 160{
161 if (user_mode(regs) && (regs->ARM_cpsr & PSR_I_BIT) == 0) { 161 unsigned long mode = regs->ARM_cpsr & MODE_MASK;
162 regs->ARM_cpsr &= ~(PSR_F_BIT | PSR_A_BIT); 162
163 return 1; 163 /*
164 * Always clear the F (FIQ) and A (delayed abort) bits
165 */
166 regs->ARM_cpsr &= ~(PSR_F_BIT | PSR_A_BIT);
167
168 if ((regs->ARM_cpsr & PSR_I_BIT) == 0) {
169 if (mode == USR_MODE)
170 return 1;
171 if (elf_hwcap & HWCAP_26BIT && mode == USR26_MODE)
172 return 1;
164 } 173 }
165 174
166 /* 175 /*
167 * Force CPSR to something logical... 176 * Force CPSR to something logical...
168 */ 177 */
169 regs->ARM_cpsr &= PSR_f | PSR_s | (PSR_x & ~PSR_A_BIT) | PSR_T_BIT | MODE32_BIT; 178 regs->ARM_cpsr &= PSR_f | PSR_s | PSR_x | PSR_T_BIT | MODE32_BIT;
170 if (!(elf_hwcap & HWCAP_26BIT)) 179 if (!(elf_hwcap & HWCAP_26BIT))
171 regs->ARM_cpsr |= USR_MODE; 180 regs->ARM_cpsr |= USR_MODE;
172 181