aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2009-04-30 15:12:13 -0400
committerThomas Gleixner <tglx@linutronix.de>2009-04-30 15:16:49 -0400
commit3c56999eec7acc105a31b4546c94aad2fb844b13 (patch)
tree293aef41f1441875323541cbc4f790c291b83679 /kernel
parentbad760089c1ef7fe525c0f268a4078b9cb483903 (diff)
parent12d161147f828192b5bcc33166f468a827832767 (diff)
Merge branch 'core/signal' into perfcounters/core
This is necessary to avoid the conflict of syscall numbers. Conflicts: arch/x86/ia32/ia32entry.S arch/x86/include/asm/unistd_32.h arch/x86/include/asm/unistd_64.h Fixes up the borked syscall numbers of perfcounters versus preadv/pwritev as well. Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/compat.c11
-rw-r--r--kernel/signal.c56
2 files changed, 55 insertions, 12 deletions
diff --git a/kernel/compat.c b/kernel/compat.c
index 42d56544460f..f6c204f07ea6 100644
--- a/kernel/compat.c
+++ b/kernel/compat.c
@@ -882,6 +882,17 @@ compat_sys_rt_sigtimedwait (compat_sigset_t __user *uthese,
882 882
883} 883}
884 884
885asmlinkage long
886compat_sys_rt_tgsigqueueinfo(compat_pid_t tgid, compat_pid_t pid, int sig,
887 struct compat_siginfo __user *uinfo)
888{
889 siginfo_t info;
890
891 if (copy_siginfo_from_user32(&info, uinfo))
892 return -EFAULT;
893 return do_rt_tgsigqueueinfo(tgid, pid, sig, &info);
894}
895
885#ifdef __ARCH_WANT_COMPAT_SYS_TIME 896#ifdef __ARCH_WANT_COMPAT_SYS_TIME
886 897
887/* compat_time_t is a 32 bit "long" and needs to get converted. */ 898/* compat_time_t is a 32 bit "long" and needs to get converted. */
diff --git a/kernel/signal.c b/kernel/signal.c
index d8034737db4c..f79b3b9f8375 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -2278,24 +2278,17 @@ SYSCALL_DEFINE2(kill, pid_t, pid, int, sig)
2278 return kill_something_info(sig, &info, pid); 2278 return kill_something_info(sig, &info, pid);
2279} 2279}
2280 2280
2281static int do_tkill(pid_t tgid, pid_t pid, int sig) 2281static int
2282do_send_specific(pid_t tgid, pid_t pid, int sig, struct siginfo *info)
2282{ 2283{
2283 int error;
2284 struct siginfo info;
2285 struct task_struct *p; 2284 struct task_struct *p;
2286 unsigned long flags; 2285 unsigned long flags;
2287 2286 int error = -ESRCH;
2288 error = -ESRCH;
2289 info.si_signo = sig;
2290 info.si_errno = 0;
2291 info.si_code = SI_TKILL;
2292 info.si_pid = task_tgid_vnr(current);
2293 info.si_uid = current_uid();
2294 2287
2295 rcu_read_lock(); 2288 rcu_read_lock();
2296 p = find_task_by_vpid(pid); 2289 p = find_task_by_vpid(pid);
2297 if (p && (tgid <= 0 || task_tgid_vnr(p) == tgid)) { 2290 if (p && (tgid <= 0 || task_tgid_vnr(p) == tgid)) {
2298 error = check_kill_permission(sig, &info, p); 2291 error = check_kill_permission(sig, info, p);
2299 /* 2292 /*
2300 * The null signal is a permissions and process existence 2293 * The null signal is a permissions and process existence
2301 * probe. No signal is actually delivered. 2294 * probe. No signal is actually delivered.
@@ -2305,7 +2298,7 @@ static int do_tkill(pid_t tgid, pid_t pid, int sig)
2305 * signal is private anyway. 2298 * signal is private anyway.
2306 */ 2299 */
2307 if (!error && sig && lock_task_sighand(p, &flags)) { 2300 if (!error && sig && lock_task_sighand(p, &flags)) {
2308 error = specific_send_sig_info(sig, &info, p); 2301 error = specific_send_sig_info(sig, info, p);
2309 unlock_task_sighand(p, &flags); 2302 unlock_task_sighand(p, &flags);
2310 } 2303 }
2311 } 2304 }
@@ -2314,6 +2307,19 @@ static int do_tkill(pid_t tgid, pid_t pid, int sig)
2314 return error; 2307 return error;
2315} 2308}
2316 2309
2310static int do_tkill(pid_t tgid, pid_t pid, int sig)
2311{
2312 struct siginfo info;
2313
2314 info.si_signo = sig;
2315 info.si_errno = 0;
2316 info.si_code = SI_TKILL;
2317 info.si_pid = task_tgid_vnr(current);
2318 info.si_uid = current_uid();
2319
2320 return do_send_specific(tgid, pid, sig, &info);
2321}
2322
2317/** 2323/**
2318 * sys_tgkill - send signal to one specific thread 2324 * sys_tgkill - send signal to one specific thread
2319 * @tgid: the thread group ID of the thread 2325 * @tgid: the thread group ID of the thread
@@ -2363,6 +2369,32 @@ SYSCALL_DEFINE3(rt_sigqueueinfo, pid_t, pid, int, sig,
2363 return kill_proc_info(sig, &info, pid); 2369 return kill_proc_info(sig, &info, pid);
2364} 2370}
2365 2371
2372long do_rt_tgsigqueueinfo(pid_t tgid, pid_t pid, int sig, siginfo_t *info)
2373{
2374 /* This is only valid for single tasks */
2375 if (pid <= 0 || tgid <= 0)
2376 return -EINVAL;
2377
2378 /* Not even root can pretend to send signals from the kernel.
2379 Nor can they impersonate a kill(), which adds source info. */
2380 if (info->si_code >= 0)
2381 return -EPERM;
2382 info->si_signo = sig;
2383
2384 return do_send_specific(tgid, pid, sig, info);
2385}
2386
2387SYSCALL_DEFINE4(rt_tgsigqueueinfo, pid_t, tgid, pid_t, pid, int, sig,
2388 siginfo_t __user *, uinfo)
2389{
2390 siginfo_t info;
2391
2392 if (copy_from_user(&info, uinfo, sizeof(siginfo_t)))
2393 return -EFAULT;
2394
2395 return do_rt_tgsigqueueinfo(tgid, pid, sig, &info);
2396}
2397
2366int do_sigaction(int sig, struct k_sigaction *act, struct k_sigaction *oact) 2398int do_sigaction(int sig, struct k_sigaction *act, struct k_sigaction *oact)
2367{ 2399{
2368 struct task_struct *t = current; 2400 struct task_struct *t = current;