mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH 1/5] mn10300: Avoid SIGSEGV delivery loop
@ 2010-09-27 10:47 David Howells
  2010-09-27 10:47 ` [PATCH 2/5] mn10300: Prevent double syscall restarts David Howells
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: David Howells @ 2010-09-27 10:47 UTC (permalink / raw)
  To: torvalds, akpm; +Cc: linux-am33-list, linux-kernel, Al Viro, David Howells

From: Al Viro <viro@ftp.linux.org.uk>

Use force_sigsegv() rather than force_sig(SIGSEGV, ...) as the former resets
the SEGV handler pointer which will kill the process, rather than leaving it
open to an infinite loop if the SEGV handler itself caused a SEGV signal.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: David Howells <dhowells@redhat.com>
---

 arch/mn10300/kernel/signal.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)


diff --git a/arch/mn10300/kernel/signal.c b/arch/mn10300/kernel/signal.c
index 717db14..57178a8 100644
--- a/arch/mn10300/kernel/signal.c
+++ b/arch/mn10300/kernel/signal.c
@@ -345,7 +345,7 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
 	return 0;
 
 give_sigsegv:
-	force_sig(SIGSEGV, current);
+	force_sigsegv(sig, current);
 	return -EFAULT;
 }
 
@@ -428,7 +428,7 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
 	return 0;
 
 give_sigsegv:
-	force_sig(SIGSEGV, current);
+	force_sigsegv(sig, current);
 	return -EFAULT;
 }
 


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 2/5] mn10300: Prevent double syscall restarts
  2010-09-27 10:47 [PATCH 1/5] mn10300: Avoid SIGSEGV delivery loop David Howells
@ 2010-09-27 10:47 ` David Howells
  2010-09-27 10:47 ` [PATCH 3/5] mn10300: ->restart_block.fn needs to be reset on sigreturn David Howells
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: David Howells @ 2010-09-27 10:47 UTC (permalink / raw)
  To: torvalds, akpm; +Cc: linux-am33-list, linux-kernel, Al Viro, David Howells

From: Al Viro <viro@ftp.linux.org.uk>

We need to make sure that only the first do_signal() to be handled on
the way out of the syscall handler will bother with syscall restarts.

We do this by setting orig_d0 to -1 as sigreturn does.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: David Howells <dhowells@redhat.com>
---

 arch/mn10300/kernel/signal.c |   12 +++++++++---
 1 files changed, 9 insertions(+), 3 deletions(-)


diff --git a/arch/mn10300/kernel/signal.c b/arch/mn10300/kernel/signal.c
index 57178a8..4ef9925 100644
--- a/arch/mn10300/kernel/signal.c
+++ b/arch/mn10300/kernel/signal.c
@@ -432,6 +432,12 @@ give_sigsegv:
 	return -EFAULT;
 }
 
+static inline void stepback(struct pt_regs *regs)
+{
+	regs->pc -= 2;
+	regs->orig_d0 = -1;
+}
+
 /*
  * handle the actual delivery of a signal to userspace
  */
@@ -459,7 +465,7 @@ static int handle_signal(int sig,
 			/* fallthrough */
 		case -ERESTARTNOINTR:
 			regs->d0 = regs->orig_d0;
-			regs->pc -= 2;
+			stepback(regs);
 		}
 	}
 
@@ -527,12 +533,12 @@ static void do_signal(struct pt_regs *regs)
 		case -ERESTARTSYS:
 		case -ERESTARTNOINTR:
 			regs->d0 = regs->orig_d0;
-			regs->pc -= 2;
+			stepback(regs);
 			break;
 
 		case -ERESTART_RESTARTBLOCK:
 			regs->d0 = __NR_restart_syscall;
-			regs->pc -= 2;
+			stepback(regs);
 			break;
 		}
 	}


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 3/5] mn10300: ->restart_block.fn needs to be reset on sigreturn
  2010-09-27 10:47 [PATCH 1/5] mn10300: Avoid SIGSEGV delivery loop David Howells
  2010-09-27 10:47 ` [PATCH 2/5] mn10300: Prevent double syscall restarts David Howells
@ 2010-09-27 10:47 ` David Howells
  2010-09-27 10:48 ` [PATCH 4/5] mn10300: Get rid of set_fs(USER_DS) in sigframe setup David Howells
  2010-09-27 10:48 ` [PATCH 5/5] mn10300: Check __get/put_user() results David Howells
  3 siblings, 0 replies; 5+ messages in thread
From: David Howells @ 2010-09-27 10:47 UTC (permalink / raw)
  To: torvalds, akpm; +Cc: linux-am33-list, linux-kernel, Al Viro, David Howells

From: Al Viro <viro@ftp.linux.org.uk>

Reset restart_block.fn on executing a sigreturn such that any currently
pending system call restarts will be forced to return -EINTR.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: David Howells <dhowells@redhat.com>
---

 arch/mn10300/kernel/signal.c |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)


diff --git a/arch/mn10300/kernel/signal.c b/arch/mn10300/kernel/signal.c
index 4ef9925..5a2c004 100644
--- a/arch/mn10300/kernel/signal.c
+++ b/arch/mn10300/kernel/signal.c
@@ -102,6 +102,9 @@ static int restore_sigcontext(struct pt_regs *regs,
 {
 	unsigned int err = 0;
 
+	/* Always make any pending restarted system calls return -EINTR */
+	current_thread_info()->restart_block.fn = do_no_restart_syscall;
+
 	if (is_using_fpu(current))
 		fpu_kill_state(current);
 


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 4/5] mn10300: Get rid of set_fs(USER_DS) in sigframe setup
  2010-09-27 10:47 [PATCH 1/5] mn10300: Avoid SIGSEGV delivery loop David Howells
  2010-09-27 10:47 ` [PATCH 2/5] mn10300: Prevent double syscall restarts David Howells
  2010-09-27 10:47 ` [PATCH 3/5] mn10300: ->restart_block.fn needs to be reset on sigreturn David Howells
@ 2010-09-27 10:48 ` David Howells
  2010-09-27 10:48 ` [PATCH 5/5] mn10300: Check __get/put_user() results David Howells
  3 siblings, 0 replies; 5+ messages in thread
From: David Howells @ 2010-09-27 10:48 UTC (permalink / raw)
  To: torvalds, akpm; +Cc: linux-am33-list, linux-kernel, Al Viro, David Howells

From: Al Viro <viro@ftp.linux.org.uk>

The set_fs(USER_DS) in the signal frame setup code really has no business
being there; short of a serious kernel bug we should already have USER_DS at
that point.  It shouldn't have been done on x86 either...

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: David Howells <dhowells@redhat.com>
---

 arch/mn10300/kernel/signal.c |    4 ----
 1 files changed, 0 insertions(+), 4 deletions(-)


diff --git a/arch/mn10300/kernel/signal.c b/arch/mn10300/kernel/signal.c
index 5a2c004..ae36480 100644
--- a/arch/mn10300/kernel/signal.c
+++ b/arch/mn10300/kernel/signal.c
@@ -333,8 +333,6 @@ static int setup_frame(int sig, struct k_sigaction *ka, sigset_t *set,
 	regs->d0 = sig;
 	regs->d1 = (unsigned long) &frame->sc;
 
-	set_fs(USER_DS);
-
 	/* the tracer may want to single-step inside the handler */
 	if (test_thread_flag(TIF_SINGLESTEP))
 		ptrace_notify(SIGTRAP);
@@ -416,8 +414,6 @@ static int setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info,
 	regs->d0 = sig;
 	regs->d1 = (long) &frame->info;
 
-	set_fs(USER_DS);
-
 	/* the tracer may want to single-step inside the handler */
 	if (test_thread_flag(TIF_SINGLESTEP))
 		ptrace_notify(SIGTRAP);


^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 5/5] mn10300: Check __get/put_user() results
  2010-09-27 10:47 [PATCH 1/5] mn10300: Avoid SIGSEGV delivery loop David Howells
                   ` (2 preceding siblings ...)
  2010-09-27 10:48 ` [PATCH 4/5] mn10300: Get rid of set_fs(USER_DS) in sigframe setup David Howells
@ 2010-09-27 10:48 ` David Howells
  3 siblings, 0 replies; 5+ messages in thread
From: David Howells @ 2010-09-27 10:48 UTC (permalink / raw)
  To: torvalds, akpm; +Cc: linux-am33-list, linux-kernel, Al Viro, David Howells

From: Al Viro <viro@ftp.linux.org.uk>

The results of calling __get/put_user() in sys_sigaction must be checked so
that EFAULT conditions don't go unreported.

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: David Howells <dhowells@redhat.com>
---

 arch/mn10300/kernel/signal.c |   12 ++++++------
 1 files changed, 6 insertions(+), 6 deletions(-)


diff --git a/arch/mn10300/kernel/signal.c b/arch/mn10300/kernel/signal.c
index ae36480..d4de05a 100644
--- a/arch/mn10300/kernel/signal.c
+++ b/arch/mn10300/kernel/signal.c
@@ -65,10 +65,10 @@ asmlinkage long sys_sigaction(int sig,
 		old_sigset_t mask;
 		if (verify_area(VERIFY_READ, act, sizeof(*act)) ||
 		    __get_user(new_ka.sa.sa_handler, &act->sa_handler) ||
-		    __get_user(new_ka.sa.sa_restorer, &act->sa_restorer))
+		    __get_user(new_ka.sa.sa_restorer, &act->sa_restorer) ||
+		    __get_user(new_ka.sa.sa_flags, &act->sa_flags) ||
+		    __get_user(mask, &act->sa_mask))
 			return -EFAULT;
-		__get_user(new_ka.sa.sa_flags, &act->sa_flags);
-		__get_user(mask, &act->sa_mask);
 		siginitset(&new_ka.sa.sa_mask, mask);
 	}
 
@@ -77,10 +77,10 @@ asmlinkage long sys_sigaction(int sig,
 	if (!ret && oact) {
 		if (verify_area(VERIFY_WRITE, oact, sizeof(*oact)) ||
 		    __put_user(old_ka.sa.sa_handler, &oact->sa_handler) ||
-		    __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer))
+		    __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer) ||
+		    __put_user(old_ka.sa.sa_flags, &oact->sa_flags) ||
+		    __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask))
 			return -EFAULT;
-		__put_user(old_ka.sa.sa_flags, &oact->sa_flags);
-		__put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask);
 	}
 
 	return ret;


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2010-09-27 10:48 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-09-27 10:47 [PATCH 1/5] mn10300: Avoid SIGSEGV delivery loop David Howells
2010-09-27 10:47 ` [PATCH 2/5] mn10300: Prevent double syscall restarts David Howells
2010-09-27 10:47 ` [PATCH 3/5] mn10300: ->restart_block.fn needs to be reset on sigreturn David Howells
2010-09-27 10:48 ` [PATCH 4/5] mn10300: Get rid of set_fs(USER_DS) in sigframe setup David Howells
2010-09-27 10:48 ` [PATCH 5/5] mn10300: Check __get/put_user() results David Howells

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®