diff options
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/exit.c | 10 | ||||
| -rw-r--r-- | kernel/signal.c | 35 |
2 files changed, 25 insertions, 20 deletions
diff --git a/kernel/exit.c b/kernel/exit.c index 2d39ccc367e..537394b25e8 100644 --- a/kernel/exit.c +++ b/kernel/exit.c | |||
| @@ -547,7 +547,7 @@ static inline void reparent_thread(task_t *p, task_t *father, int traced) | |||
| 547 | 547 | ||
| 548 | if (p->pdeath_signal) | 548 | if (p->pdeath_signal) |
| 549 | /* We already hold the tasklist_lock here. */ | 549 | /* We already hold the tasklist_lock here. */ |
| 550 | group_send_sig_info(p->pdeath_signal, (void *) 0, p); | 550 | group_send_sig_info(p->pdeath_signal, SEND_SIG_NOINFO, p); |
| 551 | 551 | ||
| 552 | /* Move the child from its dying parent to the new one. */ | 552 | /* Move the child from its dying parent to the new one. */ |
| 553 | if (unlikely(traced)) { | 553 | if (unlikely(traced)) { |
| @@ -591,8 +591,8 @@ static inline void reparent_thread(task_t *p, task_t *father, int traced) | |||
| 591 | int pgrp = process_group(p); | 591 | int pgrp = process_group(p); |
| 592 | 592 | ||
| 593 | if (will_become_orphaned_pgrp(pgrp, NULL) && has_stopped_jobs(pgrp)) { | 593 | if (will_become_orphaned_pgrp(pgrp, NULL) && has_stopped_jobs(pgrp)) { |
| 594 | __kill_pg_info(SIGHUP, (void *)1, pgrp); | 594 | __kill_pg_info(SIGHUP, SEND_SIG_PRIV, pgrp); |
| 595 | __kill_pg_info(SIGCONT, (void *)1, pgrp); | 595 | __kill_pg_info(SIGCONT, SEND_SIG_PRIV, pgrp); |
| 596 | } | 596 | } |
| 597 | } | 597 | } |
| 598 | } | 598 | } |
| @@ -727,8 +727,8 @@ static void exit_notify(struct task_struct *tsk) | |||
| 727 | (t->signal->session == tsk->signal->session) && | 727 | (t->signal->session == tsk->signal->session) && |
| 728 | will_become_orphaned_pgrp(process_group(tsk), tsk) && | 728 | will_become_orphaned_pgrp(process_group(tsk), tsk) && |
| 729 | has_stopped_jobs(process_group(tsk))) { | 729 | has_stopped_jobs(process_group(tsk))) { |
| 730 | __kill_pg_info(SIGHUP, (void *)1, process_group(tsk)); | 730 | __kill_pg_info(SIGHUP, SEND_SIG_PRIV, process_group(tsk)); |
| 731 | __kill_pg_info(SIGCONT, (void *)1, process_group(tsk)); | 731 | __kill_pg_info(SIGCONT, SEND_SIG_PRIV, process_group(tsk)); |
| 732 | } | 732 | } |
| 733 | 733 | ||
| 734 | /* Let father know we died | 734 | /* Let father know we died |
diff --git a/kernel/signal.c b/kernel/signal.c index 9d1512dcf17..1f7b2aaa4a3 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 | |||
| 1288 | int | 1293 | int |
| 1289 | send_sig(int sig, struct task_struct *p, int priv) | 1294 | send_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) | |||
| 1308 | void | 1313 | void |
| 1309 | force_sig(int sig, struct task_struct *p) | 1314 | force_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) | |||
| 1333 | int | 1338 | int |
| 1334 | kill_pg(pid_t pgrp, int sig, int priv) | 1339 | kill_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 | ||
| 1339 | int | 1344 | int |
| 1340 | kill_proc(pid_t pid, int sig, int priv) | 1345 | kill_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 | /* |
