]> git.kernelconcepts.de Git - karo-tx-linux.git/blobdiff - kernel/ptrace.c
ptrace: add ability to get/set signal-blocked mask
[karo-tx-linux.git] / kernel / ptrace.c
index 335a7ae697f5986269d94a445fd27142fc75c09f..ba5e6cea181afecb583d567c38c23008142567c9 100644 (file)
@@ -844,6 +844,47 @@ int ptrace_request(struct task_struct *child, long request,
                        ret = ptrace_setsiginfo(child, &siginfo);
                break;
 
+       case PTRACE_GETSIGMASK:
+               if (addr != sizeof(sigset_t)) {
+                       ret = -EINVAL;
+                       break;
+               }
+
+               if (copy_to_user(datavp, &child->blocked, sizeof(sigset_t)))
+                       ret = -EFAULT;
+               else
+                       ret = 0;
+
+               break;
+
+       case PTRACE_SETSIGMASK: {
+               sigset_t new_set;
+
+               if (addr != sizeof(sigset_t)) {
+                       ret = -EINVAL;
+                       break;
+               }
+
+               if (copy_from_user(&new_set, datavp, sizeof(sigset_t))) {
+                       ret = -EFAULT;
+                       break;
+               }
+
+               sigdelsetmask(&new_set, sigmask(SIGKILL)|sigmask(SIGSTOP));
+
+               /*
+                * Every thread does recalc_sigpending() after resume, so
+                * retarget_shared_pending() and recalc_sigpending() are not
+                * called here.
+                */
+               spin_lock_irq(&child->sighand->siglock);
+               child->blocked = new_set;
+               spin_unlock_irq(&child->sighand->siglock);
+
+               ret = 0;
+               break;
+       }
+
        case PTRACE_INTERRUPT:
                /*
                 * Stop tracee without any side-effect on signal or job
@@ -948,8 +989,7 @@ int ptrace_request(struct task_struct *child, long request,
 
 #ifdef CONFIG_HAVE_ARCH_TRACEHOOK
        case PTRACE_GETREGSET:
-       case PTRACE_SETREGSET:
-       {
+       case PTRACE_SETREGSET: {
                struct iovec kiov;
                struct iovec __user *uiov = datavp;