aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/signal.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/signal.c')
-rw-r--r--kernel/signal.c71
1 files changed, 25 insertions, 46 deletions
diff --git a/kernel/signal.c b/kernel/signal.c
index 8d6e64dfa5c6..1d905ec74bde 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -2283,26 +2283,13 @@ sys_kill(int pid, int sig)
2283 return kill_something_info(sig, &info, pid); 2283 return kill_something_info(sig, &info, pid);
2284} 2284}
2285 2285
2286/** 2286static int do_tkill(int tgid, int pid, int sig)
2287 * sys_tgkill - send signal to one specific thread
2288 * @tgid: the thread group ID of the thread
2289 * @pid: the PID of the thread
2290 * @sig: signal to be sent
2291 *
2292 * This syscall also checks the tgid and returns -ESRCH even if the PID
2293 * exists but it's not belonging to the target process anymore. This
2294 * method solves the problem of threads exiting and PIDs getting reused.
2295 */
2296asmlinkage long sys_tgkill(int tgid, int pid, int sig)
2297{ 2287{
2298 struct siginfo info;
2299 int error; 2288 int error;
2289 struct siginfo info;
2300 struct task_struct *p; 2290 struct task_struct *p;
2301 2291
2302 /* This is only valid for single tasks */ 2292 error = -ESRCH;
2303 if (pid <= 0 || tgid <= 0)
2304 return -EINVAL;
2305
2306 info.si_signo = sig; 2293 info.si_signo = sig;
2307 info.si_errno = 0; 2294 info.si_errno = 0;
2308 info.si_code = SI_TKILL; 2295 info.si_code = SI_TKILL;
@@ -2311,8 +2298,7 @@ asmlinkage long sys_tgkill(int tgid, int pid, int sig)
2311 2298
2312 read_lock(&tasklist_lock); 2299 read_lock(&tasklist_lock);
2313 p = find_task_by_pid(pid); 2300 p = find_task_by_pid(pid);
2314 error = -ESRCH; 2301 if (p && (tgid <= 0 || p->tgid == tgid)) {
2315 if (p && (p->tgid == tgid)) {
2316 error = check_kill_permission(sig, &info, p); 2302 error = check_kill_permission(sig, &info, p);
2317 /* 2303 /*
2318 * The null signal is a permissions and process existence 2304 * The null signal is a permissions and process existence
@@ -2326,47 +2312,40 @@ asmlinkage long sys_tgkill(int tgid, int pid, int sig)
2326 } 2312 }
2327 } 2313 }
2328 read_unlock(&tasklist_lock); 2314 read_unlock(&tasklist_lock);
2315
2329 return error; 2316 return error;
2330} 2317}
2331 2318
2319/**
2320 * sys_tgkill - send signal to one specific thread
2321 * @tgid: the thread group ID of the thread
2322 * @pid: the PID of the thread
2323 * @sig: signal to be sent
2324 *
2325 * This syscall also checks the tgid and returns -ESRCH even if the PID
2326 * exists but it's not belonging to the target process anymore. This
2327 * method solves the problem of threads exiting and PIDs getting reused.
2328 */
2329asmlinkage long sys_tgkill(int tgid, int pid, int sig)
2330{
2331 /* This is only valid for single tasks */
2332 if (pid <= 0 || tgid <= 0)
2333 return -EINVAL;
2334
2335 return do_tkill(tgid, pid, sig);
2336}
2337
2332/* 2338/*
2333 * Send a signal to only one task, even if it's a CLONE_THREAD task. 2339 * Send a signal to only one task, even if it's a CLONE_THREAD task.
2334 */ 2340 */
2335asmlinkage long 2341asmlinkage long
2336sys_tkill(int pid, int sig) 2342sys_tkill(int pid, int sig)
2337{ 2343{
2338 struct siginfo info;
2339 int error;
2340 struct task_struct *p;
2341
2342 /* This is only valid for single tasks */ 2344 /* This is only valid for single tasks */
2343 if (pid <= 0) 2345 if (pid <= 0)
2344 return -EINVAL; 2346 return -EINVAL;
2345 2347
2346 info.si_signo = sig; 2348 return do_tkill(0, pid, sig);
2347 info.si_errno = 0;
2348 info.si_code = SI_TKILL;
2349 info.si_pid = current->tgid;
2350 info.si_uid = current->uid;
2351
2352 read_lock(&tasklist_lock);
2353 p = find_task_by_pid(pid);
2354 error = -ESRCH;
2355 if (p) {
2356 error = check_kill_permission(sig, &info, p);
2357 /*
2358 * The null signal is a permissions and process existence
2359 * probe. No signal is actually delivered.
2360 */
2361 if (!error && sig && p->sighand) {
2362 spin_lock_irq(&p->sighand->siglock);
2363 handle_stop_signal(sig, p);
2364 error = specific_send_sig_info(sig, &info, p);
2365 spin_unlock_irq(&p->sighand->siglock);
2366 }
2367 }
2368 read_unlock(&tasklist_lock);
2369 return error;
2370} 2349}
2371 2350
2372asmlinkage long 2351asmlinkage long