From acf6f51ba7048e99a1f8b7d5cea70b2faf7774c7 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Arve=20Hj=C3=B8nnev=C3=A5g?= Date: Mon, 9 Apr 2007 17:13:02 +0700 Subject: [PATCH] [ARM] Add code to prevent system calls from being restarted muliple times before returning from the kernel. Fixes crashes with thumb syscalls. --- arch/arm/kernel/signal.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c index 907d5a620bca..15c46d27ca27 100644 --- a/arch/arm/kernel/signal.c +++ b/arch/arm/kernel/signal.c @@ -602,6 +602,14 @@ setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t *info, static inline void setup_syscall_restart(struct pt_regs *regs) { + if (regs->ARM_ORIG_r0 == -ERESTARTNOHAND || + regs->ARM_ORIG_r0 == -ERESTARTSYS || + regs->ARM_ORIG_r0 == -ERESTARTNOINTR || + regs->ARM_ORIG_r0 == -ERESTART_RESTARTBLOCK) { + /* the syscall cannot be safely restarted, return -EINTR instead */ + regs->ARM_r0 = -EINTR; + return; + } regs->ARM_r0 = regs->ARM_ORIG_r0; regs->ARM_pc -= thumb_mode(regs) ? 2 : 4; } @@ -734,6 +742,7 @@ static void do_signal(struct pt_regs *regs, int syscall) */ if (syscall) { if (regs->ARM_r0 == -ERESTART_RESTARTBLOCK) { + regs->ARM_r0 = -EAGAIN; /* prevent multiple restarts */ if (thumb_mode(regs)) { regs->ARM_r7 = __NR_restart_syscall - __NR_SYSCALL_BASE; regs->ARM_pc -= 2; -- 2.34.1