aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/signal.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/signal.c')
-rw-r--r--kernel/signal.c35
1 files changed, 20 insertions, 15 deletions
diff --git a/kernel/signal.c b/kernel/signal.c
index 9d1512dcf176..1f7b2aaa4a39 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -651,8 +651,9 @@ static int check_kill_permission(int sig, struct siginfo *info,
651 if (!valid_signal(sig)) 651 if (!valid_signal(sig))
652 return error; 652 return error;
653 error = -EPERM; 653 error = -EPERM;
654 if ((!info || ((unsigned long)info != 1 && 654 if ((info == SEND_SIG_NOINFO ||
655 (unsigned long)info != 2 && SI_FROMUSER(info))) 655 (info != SEND_SIG_PRIV && info != SEND_SIG_FORCED
656 && SI_FROMUSER(info)))
656 && ((sig != SIGCONT) || 657 && ((sig != SIGCONT) ||
657 (current->signal->session != t->signal->session)) 658 (current->signal->session != t->signal->session))
658 && (current->euid ^ t->suid) && (current->euid ^ t->uid) 659 && (current->euid ^ t->suid) && (current->euid ^ t->uid)
@@ -789,7 +790,7 @@ static int send_signal(int sig, struct siginfo *info, struct task_struct *t,
789 * fast-pathed signals for kernel-internal things like SIGSTOP 790 * fast-pathed signals for kernel-internal things like SIGSTOP
790 * or SIGKILL. 791 * or SIGKILL.
791 */ 792 */
792 if ((unsigned long)info == 2) 793 if (info == SEND_SIG_FORCED)
793 goto out_set; 794 goto out_set;
794 795
795 /* Real-time signals must be queued if sent by sigqueue, or 796 /* Real-time signals must be queued if sent by sigqueue, or
@@ -801,19 +802,19 @@ static int send_signal(int sig, struct siginfo *info, struct task_struct *t,
801 pass on the info struct. */ 802 pass on the info struct. */
802 803
803 q = __sigqueue_alloc(t, GFP_ATOMIC, (sig < SIGRTMIN && 804 q = __sigqueue_alloc(t, GFP_ATOMIC, (sig < SIGRTMIN &&
804 ((unsigned long) info < 2 || 805 (info < SEND_SIG_FORCED ||
805 info->si_code >= 0))); 806 info->si_code >= 0)));
806 if (q) { 807 if (q) {
807 list_add_tail(&q->list, &signals->list); 808 list_add_tail(&q->list, &signals->list);
808 switch ((unsigned long) info) { 809 switch ((unsigned long) info) {
809 case 0: 810 case (unsigned long) SEND_SIG_NOINFO:
810 q->info.si_signo = sig; 811 q->info.si_signo = sig;
811 q->info.si_errno = 0; 812 q->info.si_errno = 0;
812 q->info.si_code = SI_USER; 813 q->info.si_code = SI_USER;
813 q->info.si_pid = current->pid; 814 q->info.si_pid = current->pid;
814 q->info.si_uid = current->uid; 815 q->info.si_uid = current->uid;
815 break; 816 break;
816 case 1: 817 case (unsigned long) SEND_SIG_PRIV:
817 q->info.si_signo = sig; 818 q->info.si_signo = sig;
818 q->info.si_errno = 0; 819 q->info.si_errno = 0;
819 q->info.si_code = SI_KERNEL; 820 q->info.si_code = SI_KERNEL;
@@ -825,14 +826,15 @@ static int send_signal(int sig, struct siginfo *info, struct task_struct *t,
825 break; 826 break;
826 } 827 }
827 } else { 828 } else {
828 if (sig >= SIGRTMIN && info && (unsigned long)info != 1 829 if (sig >= SIGRTMIN
830 && info != SEND_SIG_NOINFO && info != SEND_SIG_PRIV
829 && info->si_code != SI_USER) 831 && info->si_code != SI_USER)
830 /* 832 /*
831 * Queue overflow, abort. We may abort if the signal was rt 833 * Queue overflow, abort. We may abort if the signal was rt
832 * and sent by user using something other than kill(). 834 * and sent by user using something other than kill().
833 */ 835 */
834 return -EAGAIN; 836 return -EAGAIN;
835 if (((unsigned long)info > 1) && (info->si_code == SI_TIMER)) 837 if ((info > SEND_SIG_PRIV) && (info->si_code == SI_TIMER))
836 /* 838 /*
837 * Set up a return to indicate that we dropped 839 * Set up a return to indicate that we dropped
838 * the signal. 840 * the signal.
@@ -858,7 +860,7 @@ specific_send_sig_info(int sig, struct siginfo *info, struct task_struct *t)
858 BUG(); 860 BUG();
859 assert_spin_locked(&t->sighand->siglock); 861 assert_spin_locked(&t->sighand->siglock);
860 862
861 if (((unsigned long)info > 2) && (info->si_code == SI_TIMER)) 863 if ((info > SEND_SIG_FORCED) && (info->si_code == SI_TIMER))
862 /* 864 /*
863 * Set up a return to indicate that we dropped the signal. 865 * Set up a return to indicate that we dropped the signal.
864 */ 866 */
@@ -914,7 +916,7 @@ force_sig_specific(int sig, struct task_struct *t)
914 t->sighand->action[sig-1].sa.sa_handler = SIG_DFL; 916 t->sighand->action[sig-1].sa.sa_handler = SIG_DFL;
915 sigdelset(&t->blocked, sig); 917 sigdelset(&t->blocked, sig);
916 recalc_sigpending_tsk(t); 918 recalc_sigpending_tsk(t);
917 specific_send_sig_info(sig, (void *)2, t); 919 specific_send_sig_info(sig, SEND_SIG_FORCED, t);
918 spin_unlock_irqrestore(&t->sighand->siglock, flags); 920 spin_unlock_irqrestore(&t->sighand->siglock, flags);
919} 921}
920 922
@@ -1050,7 +1052,7 @@ __group_send_sig_info(int sig, struct siginfo *info, struct task_struct *p)
1050 assert_spin_locked(&p->sighand->siglock); 1052 assert_spin_locked(&p->sighand->siglock);
1051 handle_stop_signal(sig, p); 1053 handle_stop_signal(sig, p);
1052 1054
1053 if (((unsigned long)info > 2) && (info->si_code == SI_TIMER)) 1055 if ((info > SEND_SIG_FORCED) && (info->si_code == SI_TIMER))
1054 /* 1056 /*
1055 * Set up a return to indicate that we dropped the signal. 1057 * Set up a return to indicate that we dropped the signal.
1056 */ 1058 */
@@ -1285,10 +1287,13 @@ send_sig_info(int sig, struct siginfo *info, struct task_struct *p)
1285 return ret; 1287 return ret;
1286} 1288}
1287 1289
1290#define __si_special(priv) \
1291 ((priv) ? SEND_SIG_PRIV : SEND_SIG_NOINFO)
1292
1288int 1293int
1289send_sig(int sig, struct task_struct *p, int priv) 1294send_sig(int sig, struct task_struct *p, int priv)
1290{ 1295{
1291 return send_sig_info(sig, (void*)(long)(priv != 0), p); 1296 return send_sig_info(sig, __si_special(priv), p);
1292} 1297}
1293 1298
1294/* 1299/*
@@ -1308,7 +1313,7 @@ send_group_sig_info(int sig, struct siginfo *info, struct task_struct *p)
1308void 1313void
1309force_sig(int sig, struct task_struct *p) 1314force_sig(int sig, struct task_struct *p)
1310{ 1315{
1311 force_sig_info(sig, (void*)1L, p); 1316 force_sig_info(sig, SEND_SIG_PRIV, p);
1312} 1317}
1313 1318
1314/* 1319/*
@@ -1333,13 +1338,13 @@ force_sigsegv(int sig, struct task_struct *p)
1333int 1338int
1334kill_pg(pid_t pgrp, int sig, int priv) 1339kill_pg(pid_t pgrp, int sig, int priv)
1335{ 1340{
1336 return kill_pg_info(sig, (void *)(long)(priv != 0), pgrp); 1341 return kill_pg_info(sig, __si_special(priv), pgrp);
1337} 1342}
1338 1343
1339int 1344int
1340kill_proc(pid_t pid, int sig, int priv) 1345kill_proc(pid_t pid, int sig, int priv)
1341{ 1346{
1342 return kill_proc_info(sig, (void *)(long)(priv != 0), pid); 1347 return kill_proc_info(sig, __si_special(priv), pid);
1343} 1348}
1344 1349
1345/* 1350/*