diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-23 21:11:45 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-05-23 21:11:45 -0400 |
commit | f9369910a6225b8d4892c3f20ae740a711cd5ace (patch) | |
tree | 8650ff79d7607bceb35509c028400ecf1c317de0 /kernel | |
parent | 05f144a0d5c2207a0349348127f996e104ad7404 (diff) | |
parent | 415d04d08fec74b226c92c1fb54ad117c9c6bac4 (diff) |
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/signal
Pull first series of signal handling cleanups from Al Viro:
"This is just the first part of the queue (about a half of it);
assorted fixes all over the place in signal handling.
This one ends with all sigsuspend() implementations switched to
generic one (->saved_sigmask-based).
With this, a bunch of assorted old buglets are fixed and most of the
missing bits of NOTIFY_RESUME hookup are in place. Two more fixes sit
in arm and um trees respectively, and there's a couple of broken ones
that need obvious fixes - parisc and avr32 check TIF_NOTIFY_RESUME
only on one of two codepaths; fixes for that will happen in the next
series"
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/signal: (55 commits)
unicore32: if there's no handler we need to restore sigmask, syscall or no syscall
xtensa: add handling of TIF_NOTIFY_RESUME
microblaze: drop 'oldset' argument of do_notify_resume()
microblaze: handle TIF_NOTIFY_RESUME
score: add handling of NOTIFY_RESUME to do_notify_resume()
m68k: add TIF_NOTIFY_RESUME and handle it.
sparc: kill ancient comment in sparc_sigaction()
h8300: missing checks of __get_user()/__put_user() return values
frv: missing checks of __get_user()/__put_user() return values
cris: missing checks of __get_user()/__put_user() return values
powerpc: missing checks of __get_user()/__put_user() return values
sh: missing checks of __get_user()/__put_user() return values
sparc: missing checks of __get_user()/__put_user() return values
avr32: struct old_sigaction is never used
m32r: struct old_sigaction is never used
xtensa: xtensa_sigaction doesn't exist
alpha: tidy signal delivery up
score: don't open-code force_sigsegv()
cris: don't open-code force_sigsegv()
blackfin: don't open-code force_sigsegv()
...
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/compat.c | 10 | ||||
-rw-r--r-- | kernel/signal.c | 25 |
2 files changed, 17 insertions, 18 deletions
diff --git a/kernel/compat.c b/kernel/compat.c index d2c67aa49ae6..c28a306ae05c 100644 --- a/kernel/compat.c +++ b/kernel/compat.c | |||
@@ -1073,15 +1073,7 @@ asmlinkage long compat_sys_rt_sigsuspend(compat_sigset_t __user *unewset, compat | |||
1073 | if (copy_from_user(&newset32, unewset, sizeof(compat_sigset_t))) | 1073 | if (copy_from_user(&newset32, unewset, sizeof(compat_sigset_t))) |
1074 | return -EFAULT; | 1074 | return -EFAULT; |
1075 | sigset_from_compat(&newset, &newset32); | 1075 | sigset_from_compat(&newset, &newset32); |
1076 | sigdelsetmask(&newset, sigmask(SIGKILL)|sigmask(SIGSTOP)); | 1076 | return sigsuspend(&newset); |
1077 | |||
1078 | current->saved_sigmask = current->blocked; | ||
1079 | set_current_blocked(&newset); | ||
1080 | |||
1081 | current->state = TASK_INTERRUPTIBLE; | ||
1082 | schedule(); | ||
1083 | set_restore_sigmask(); | ||
1084 | return -ERESTARTNOHAND; | ||
1085 | } | 1077 | } |
1086 | #endif /* __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND */ | 1078 | #endif /* __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND */ |
1087 | 1079 | ||
diff --git a/kernel/signal.c b/kernel/signal.c index 21ebe75ff85f..4dbf00dfb359 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
@@ -3232,6 +3232,21 @@ SYSCALL_DEFINE0(pause) | |||
3232 | 3232 | ||
3233 | #endif | 3233 | #endif |
3234 | 3234 | ||
3235 | #ifdef HAVE_SET_RESTORE_SIGMASK | ||
3236 | int sigsuspend(sigset_t *set) | ||
3237 | { | ||
3238 | sigdelsetmask(set, sigmask(SIGKILL)|sigmask(SIGSTOP)); | ||
3239 | |||
3240 | current->saved_sigmask = current->blocked; | ||
3241 | set_current_blocked(set); | ||
3242 | |||
3243 | current->state = TASK_INTERRUPTIBLE; | ||
3244 | schedule(); | ||
3245 | set_restore_sigmask(); | ||
3246 | return -ERESTARTNOHAND; | ||
3247 | } | ||
3248 | #endif | ||
3249 | |||
3235 | #ifdef __ARCH_WANT_SYS_RT_SIGSUSPEND | 3250 | #ifdef __ARCH_WANT_SYS_RT_SIGSUSPEND |
3236 | /** | 3251 | /** |
3237 | * sys_rt_sigsuspend - replace the signal mask for a value with the | 3252 | * sys_rt_sigsuspend - replace the signal mask for a value with the |
@@ -3249,15 +3264,7 @@ SYSCALL_DEFINE2(rt_sigsuspend, sigset_t __user *, unewset, size_t, sigsetsize) | |||
3249 | 3264 | ||
3250 | if (copy_from_user(&newset, unewset, sizeof(newset))) | 3265 | if (copy_from_user(&newset, unewset, sizeof(newset))) |
3251 | return -EFAULT; | 3266 | return -EFAULT; |
3252 | sigdelsetmask(&newset, sigmask(SIGKILL)|sigmask(SIGSTOP)); | 3267 | return sigsuspend(&newset); |
3253 | |||
3254 | current->saved_sigmask = current->blocked; | ||
3255 | set_current_blocked(&newset); | ||
3256 | |||
3257 | current->state = TASK_INTERRUPTIBLE; | ||
3258 | schedule(); | ||
3259 | set_restore_sigmask(); | ||
3260 | return -ERESTARTNOHAND; | ||
3261 | } | 3268 | } |
3262 | #endif /* __ARCH_WANT_SYS_RT_SIGSUSPEND */ | 3269 | #endif /* __ARCH_WANT_SYS_RT_SIGSUSPEND */ |
3263 | 3270 | ||