aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/compat.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/compat.c')
-rw-r--r--kernel/compat.c73
1 files changed, 47 insertions, 26 deletions
diff --git a/kernel/compat.c b/kernel/compat.c
index 74ff8498809a..c28a306ae05c 100644
--- a/kernel/compat.c
+++ b/kernel/compat.c
@@ -372,25 +372,54 @@ asmlinkage long compat_sys_sigpending(compat_old_sigset_t __user *set)
372 372
373#ifdef __ARCH_WANT_SYS_SIGPROCMASK 373#ifdef __ARCH_WANT_SYS_SIGPROCMASK
374 374
375asmlinkage long compat_sys_sigprocmask(int how, compat_old_sigset_t __user *set, 375/*
376 compat_old_sigset_t __user *oset) 376 * sys_sigprocmask SIG_SETMASK sets the first (compat) word of the
377 * blocked set of signals to the supplied signal set
378 */
379static inline void compat_sig_setmask(sigset_t *blocked, compat_sigset_word set)
377{ 380{
378 old_sigset_t s; 381 memcpy(blocked->sig, &set, sizeof(set));
379 long ret; 382}
380 mm_segment_t old_fs;
381 383
382 if (set && get_user(s, set)) 384asmlinkage long compat_sys_sigprocmask(int how,
383 return -EFAULT; 385 compat_old_sigset_t __user *nset,
384 old_fs = get_fs(); 386 compat_old_sigset_t __user *oset)
385 set_fs(KERNEL_DS); 387{
386 ret = sys_sigprocmask(how, 388 old_sigset_t old_set, new_set;
387 set ? (old_sigset_t __user *) &s : NULL, 389 sigset_t new_blocked;
388 oset ? (old_sigset_t __user *) &s : NULL); 390
389 set_fs(old_fs); 391 old_set = current->blocked.sig[0];
390 if (ret == 0) 392
391 if (oset) 393 if (nset) {
392 ret = put_user(s, oset); 394 if (get_user(new_set, nset))
393 return ret; 395 return -EFAULT;
396 new_set &= ~(sigmask(SIGKILL) | sigmask(SIGSTOP));
397
398 new_blocked = current->blocked;
399
400 switch (how) {
401 case SIG_BLOCK:
402 sigaddsetmask(&new_blocked, new_set);
403 break;
404 case SIG_UNBLOCK:
405 sigdelsetmask(&new_blocked, new_set);
406 break;
407 case SIG_SETMASK:
408 compat_sig_setmask(&new_blocked, new_set);
409 break;
410 default:
411 return -EINVAL;
412 }
413
414 set_current_blocked(&new_blocked);
415 }
416
417 if (oset) {
418 if (put_user(old_set, oset))
419 return -EFAULT;
420 }
421
422 return 0;
394} 423}
395 424
396#endif 425#endif
@@ -1044,15 +1073,7 @@ asmlinkage long compat_sys_rt_sigsuspend(compat_sigset_t __user *unewset, compat
1044 if (copy_from_user(&newset32, unewset, sizeof(compat_sigset_t))) 1073 if (copy_from_user(&newset32, unewset, sizeof(compat_sigset_t)))
1045 return -EFAULT; 1074 return -EFAULT;
1046 sigset_from_compat(&newset, &newset32); 1075 sigset_from_compat(&newset, &newset32);
1047 sigdelsetmask(&newset, sigmask(SIGKILL)|sigmask(SIGSTOP)); 1076 return sigsuspend(&newset);
1048
1049 current->saved_sigmask = current->blocked;
1050 set_current_blocked(&newset);
1051
1052 current->state = TASK_INTERRUPTIBLE;
1053 schedule();
1054 set_restore_sigmask();
1055 return -ERESTARTNOHAND;
1056} 1077}
1057#endif /* __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND */ 1078#endif /* __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND */
1058 1079