diff options
Diffstat (limited to 'kernel/signal.c')
-rw-r--r-- | kernel/signal.c | 110 |
1 files changed, 55 insertions, 55 deletions
diff --git a/kernel/signal.c b/kernel/signal.c index 8a04869402fb..3670225ecbc0 100644 --- a/kernel/signal.c +++ b/kernel/signal.c | |||
@@ -456,26 +456,50 @@ static int __dequeue_signal(struct sigpending *pending, sigset_t *mask, | |||
456 | int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info) | 456 | int dequeue_signal(struct task_struct *tsk, sigset_t *mask, siginfo_t *info) |
457 | { | 457 | { |
458 | int signr = __dequeue_signal(&tsk->pending, mask, info); | 458 | int signr = __dequeue_signal(&tsk->pending, mask, info); |
459 | if (!signr) | 459 | if (!signr) { |
460 | signr = __dequeue_signal(&tsk->signal->shared_pending, | 460 | signr = __dequeue_signal(&tsk->signal->shared_pending, |
461 | mask, info); | 461 | mask, info); |
462 | /* | ||
463 | * itimer signal ? | ||
464 | * | ||
465 | * itimers are process shared and we restart periodic | ||
466 | * itimers in the signal delivery path to prevent DoS | ||
467 | * attacks in the high resolution timer case. This is | ||
468 | * compliant with the old way of self restarting | ||
469 | * itimers, as the SIGALRM is a legacy signal and only | ||
470 | * queued once. Changing the restart behaviour to | ||
471 | * restart the timer in the signal dequeue path is | ||
472 | * reducing the timer noise on heavy loaded !highres | ||
473 | * systems too. | ||
474 | */ | ||
475 | if (unlikely(signr == SIGALRM)) { | ||
476 | struct hrtimer *tmr = &tsk->signal->real_timer; | ||
477 | |||
478 | if (!hrtimer_is_queued(tmr) && | ||
479 | tsk->signal->it_real_incr.tv64 != 0) { | ||
480 | hrtimer_forward(tmr, tmr->base->get_time(), | ||
481 | tsk->signal->it_real_incr); | ||
482 | hrtimer_restart(tmr); | ||
483 | } | ||
484 | } | ||
485 | } | ||
462 | recalc_sigpending_tsk(tsk); | 486 | recalc_sigpending_tsk(tsk); |
463 | if (signr && unlikely(sig_kernel_stop(signr))) { | 487 | if (signr && unlikely(sig_kernel_stop(signr))) { |
464 | /* | 488 | /* |
465 | * Set a marker that we have dequeued a stop signal. Our | 489 | * Set a marker that we have dequeued a stop signal. Our |
466 | * caller might release the siglock and then the pending | 490 | * caller might release the siglock and then the pending |
467 | * stop signal it is about to process is no longer in the | 491 | * stop signal it is about to process is no longer in the |
468 | * pending bitmasks, but must still be cleared by a SIGCONT | 492 | * pending bitmasks, but must still be cleared by a SIGCONT |
469 | * (and overruled by a SIGKILL). So those cases clear this | 493 | * (and overruled by a SIGKILL). So those cases clear this |
470 | * shared flag after we've set it. Note that this flag may | 494 | * shared flag after we've set it. Note that this flag may |
471 | * remain set after the signal we return is ignored or | 495 | * remain set after the signal we return is ignored or |
472 | * handled. That doesn't matter because its only purpose | 496 | * handled. That doesn't matter because its only purpose |
473 | * is to alert stop-signal processing code when another | 497 | * is to alert stop-signal processing code when another |
474 | * processor has come along and cleared the flag. | 498 | * processor has come along and cleared the flag. |
475 | */ | 499 | */ |
476 | if (!(tsk->signal->flags & SIGNAL_GROUP_EXIT)) | 500 | if (!(tsk->signal->flags & SIGNAL_GROUP_EXIT)) |
477 | tsk->signal->flags |= SIGNAL_STOP_DEQUEUED; | 501 | tsk->signal->flags |= SIGNAL_STOP_DEQUEUED; |
478 | } | 502 | } |
479 | if ( signr && | 503 | if ( signr && |
480 | ((info->si_code & __SI_MASK) == __SI_TIMER) && | 504 | ((info->si_code & __SI_MASK) == __SI_TIMER) && |
481 | info->si_sys_private){ | 505 | info->si_sys_private){ |
@@ -1096,42 +1120,21 @@ int kill_pgrp_info(int sig, struct siginfo *info, struct pid *pgrp) | |||
1096 | return retval; | 1120 | return retval; |
1097 | } | 1121 | } |
1098 | 1122 | ||
1099 | int __kill_pg_info(int sig, struct siginfo *info, pid_t pgrp) | ||
1100 | { | ||
1101 | if (pgrp <= 0) | ||
1102 | return -EINVAL; | ||
1103 | |||
1104 | return __kill_pgrp_info(sig, info, find_pid(pgrp)); | ||
1105 | } | ||
1106 | |||
1107 | int | ||
1108 | kill_pg_info(int sig, struct siginfo *info, pid_t pgrp) | ||
1109 | { | ||
1110 | int retval; | ||
1111 | |||
1112 | read_lock(&tasklist_lock); | ||
1113 | retval = __kill_pg_info(sig, info, pgrp); | ||
1114 | read_unlock(&tasklist_lock); | ||
1115 | |||
1116 | return retval; | ||
1117 | } | ||
1118 | |||
1119 | int kill_pid_info(int sig, struct siginfo *info, struct pid *pid) | 1123 | int kill_pid_info(int sig, struct siginfo *info, struct pid *pid) |
1120 | { | 1124 | { |
1121 | int error; | 1125 | int error; |
1122 | int acquired_tasklist_lock = 0; | ||
1123 | struct task_struct *p; | 1126 | struct task_struct *p; |
1124 | 1127 | ||
1125 | rcu_read_lock(); | 1128 | rcu_read_lock(); |
1126 | if (unlikely(sig_needs_tasklist(sig))) { | 1129 | if (unlikely(sig_needs_tasklist(sig))) |
1127 | read_lock(&tasklist_lock); | 1130 | read_lock(&tasklist_lock); |
1128 | acquired_tasklist_lock = 1; | 1131 | |
1129 | } | ||
1130 | p = pid_task(pid, PIDTYPE_PID); | 1132 | p = pid_task(pid, PIDTYPE_PID); |
1131 | error = -ESRCH; | 1133 | error = -ESRCH; |
1132 | if (p) | 1134 | if (p) |
1133 | error = group_send_sig_info(sig, info, p); | 1135 | error = group_send_sig_info(sig, info, p); |
1134 | if (unlikely(acquired_tasklist_lock)) | 1136 | |
1137 | if (unlikely(sig_needs_tasklist(sig))) | ||
1135 | read_unlock(&tasklist_lock); | 1138 | read_unlock(&tasklist_lock); |
1136 | rcu_read_unlock(); | 1139 | rcu_read_unlock(); |
1137 | return error; | 1140 | return error; |
@@ -1193,8 +1196,10 @@ EXPORT_SYMBOL_GPL(kill_pid_info_as_uid); | |||
1193 | 1196 | ||
1194 | static int kill_something_info(int sig, struct siginfo *info, int pid) | 1197 | static int kill_something_info(int sig, struct siginfo *info, int pid) |
1195 | { | 1198 | { |
1199 | int ret; | ||
1200 | rcu_read_lock(); | ||
1196 | if (!pid) { | 1201 | if (!pid) { |
1197 | return kill_pg_info(sig, info, process_group(current)); | 1202 | ret = kill_pgrp_info(sig, info, task_pgrp(current)); |
1198 | } else if (pid == -1) { | 1203 | } else if (pid == -1) { |
1199 | int retval = 0, count = 0; | 1204 | int retval = 0, count = 0; |
1200 | struct task_struct * p; | 1205 | struct task_struct * p; |
@@ -1209,12 +1214,14 @@ static int kill_something_info(int sig, struct siginfo *info, int pid) | |||
1209 | } | 1214 | } |
1210 | } | 1215 | } |
1211 | read_unlock(&tasklist_lock); | 1216 | read_unlock(&tasklist_lock); |
1212 | return count ? retval : -ESRCH; | 1217 | ret = count ? retval : -ESRCH; |
1213 | } else if (pid < 0) { | 1218 | } else if (pid < 0) { |
1214 | return kill_pg_info(sig, info, -pid); | 1219 | ret = kill_pgrp_info(sig, info, find_pid(-pid)); |
1215 | } else { | 1220 | } else { |
1216 | return kill_proc_info(sig, info, pid); | 1221 | ret = kill_pid_info(sig, info, find_pid(pid)); |
1217 | } | 1222 | } |
1223 | rcu_read_unlock(); | ||
1224 | return ret; | ||
1218 | } | 1225 | } |
1219 | 1226 | ||
1220 | /* | 1227 | /* |
@@ -1313,12 +1320,6 @@ int kill_pid(struct pid *pid, int sig, int priv) | |||
1313 | EXPORT_SYMBOL(kill_pid); | 1320 | EXPORT_SYMBOL(kill_pid); |
1314 | 1321 | ||
1315 | int | 1322 | int |
1316 | kill_pg(pid_t pgrp, int sig, int priv) | ||
1317 | { | ||
1318 | return kill_pg_info(sig, __si_special(priv), pgrp); | ||
1319 | } | ||
1320 | |||
1321 | int | ||
1322 | kill_proc(pid_t pid, int sig, int priv) | 1323 | kill_proc(pid_t pid, int sig, int priv) |
1323 | { | 1324 | { |
1324 | return kill_proc_info(sig, __si_special(priv), pid); | 1325 | return kill_proc_info(sig, __si_special(priv), pid); |
@@ -1907,7 +1908,7 @@ relock: | |||
1907 | 1908 | ||
1908 | /* signals can be posted during this window */ | 1909 | /* signals can be posted during this window */ |
1909 | 1910 | ||
1910 | if (is_orphaned_pgrp(process_group(current))) | 1911 | if (is_current_pgrp_orphaned()) |
1911 | goto relock; | 1912 | goto relock; |
1912 | 1913 | ||
1913 | spin_lock_irq(¤t->sighand->siglock); | 1914 | spin_lock_irq(¤t->sighand->siglock); |
@@ -1957,7 +1958,6 @@ EXPORT_SYMBOL(recalc_sigpending); | |||
1957 | EXPORT_SYMBOL_GPL(dequeue_signal); | 1958 | EXPORT_SYMBOL_GPL(dequeue_signal); |
1958 | EXPORT_SYMBOL(flush_signals); | 1959 | EXPORT_SYMBOL(flush_signals); |
1959 | EXPORT_SYMBOL(force_sig); | 1960 | EXPORT_SYMBOL(force_sig); |
1960 | EXPORT_SYMBOL(kill_pg); | ||
1961 | EXPORT_SYMBOL(kill_proc); | 1961 | EXPORT_SYMBOL(kill_proc); |
1962 | EXPORT_SYMBOL(ptrace_notify); | 1962 | EXPORT_SYMBOL(ptrace_notify); |
1963 | EXPORT_SYMBOL(send_sig); | 1963 | EXPORT_SYMBOL(send_sig); |
@@ -2284,7 +2284,7 @@ static int do_tkill(int tgid, int pid, int sig) | |||
2284 | * @pid: the PID of the thread | 2284 | * @pid: the PID of the thread |
2285 | * @sig: signal to be sent | 2285 | * @sig: signal to be sent |
2286 | * | 2286 | * |
2287 | * This syscall also checks the tgid and returns -ESRCH even if the PID | 2287 | * This syscall also checks the @tgid and returns -ESRCH even if the PID |
2288 | * exists but it's not belonging to the target process anymore. This | 2288 | * exists but it's not belonging to the target process anymore. This |
2289 | * method solves the problem of threads exiting and PIDs getting reused. | 2289 | * method solves the problem of threads exiting and PIDs getting reused. |
2290 | */ | 2290 | */ |