aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/signal.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/signal.c')
-rw-r--r--kernel/signal.c45
1 files changed, 32 insertions, 13 deletions
diff --git a/kernel/signal.c b/kernel/signal.c
index 3040c349b0e1..6cd3023cc66b 100644
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -2983,6 +2983,22 @@ SYSCALL_DEFINE2(tkill, pid_t, pid, int, sig)
2983 return do_tkill(0, pid, sig); 2983 return do_tkill(0, pid, sig);
2984} 2984}
2985 2985
2986static int do_rt_sigqueueinfo(pid_t pid, int sig, siginfo_t *info)
2987{
2988 /* Not even root can pretend to send signals from the kernel.
2989 * Nor can they impersonate a kill()/tgkill(), which adds source info.
2990 */
2991 if (info->si_code >= 0 || info->si_code == SI_TKILL) {
2992 /* We used to allow any < 0 si_code */
2993 WARN_ON_ONCE(info->si_code < 0);
2994 return -EPERM;
2995 }
2996 info->si_signo = sig;
2997
2998 /* POSIX.1b doesn't mention process groups. */
2999 return kill_proc_info(sig, info, pid);
3000}
3001
2986/** 3002/**
2987 * sys_rt_sigqueueinfo - send signal information to a signal 3003 * sys_rt_sigqueueinfo - send signal information to a signal
2988 * @pid: the PID of the thread 3004 * @pid: the PID of the thread
@@ -2993,23 +3009,26 @@ SYSCALL_DEFINE3(rt_sigqueueinfo, pid_t, pid, int, sig,
2993 siginfo_t __user *, uinfo) 3009 siginfo_t __user *, uinfo)
2994{ 3010{
2995 siginfo_t info; 3011 siginfo_t info;
2996
2997 if (copy_from_user(&info, uinfo, sizeof(siginfo_t))) 3012 if (copy_from_user(&info, uinfo, sizeof(siginfo_t)))
2998 return -EFAULT; 3013 return -EFAULT;
3014 return do_rt_sigqueueinfo(pid, sig, &info);
3015}
2999 3016
3000 /* Not even root can pretend to send signals from the kernel. 3017#ifdef CONFIG_COMPAT
3001 * Nor can they impersonate a kill()/tgkill(), which adds source info. 3018#ifdef CONFIG_GENERIC_COMPAT_RT_SIGQUEUEINFO
3002 */ 3019COMPAT_SYSCALL_DEFINE3(rt_sigqueueinfo,
3003 if (info.si_code >= 0 || info.si_code == SI_TKILL) { 3020 compat_pid_t, pid,
3004 /* We used to allow any < 0 si_code */ 3021 int, sig,
3005 WARN_ON_ONCE(info.si_code < 0); 3022 struct compat_siginfo __user *, uinfo)
3006 return -EPERM; 3023{
3007 } 3024 siginfo_t info;
3008 info.si_signo = sig; 3025 int ret = copy_siginfo_from_user32(&info, uinfo);
3009 3026 if (unlikely(ret))
3010 /* POSIX.1b doesn't mention process groups. */ 3027 return ret;
3011 return kill_proc_info(sig, &info, pid); 3028 return do_rt_sigqueueinfo(pid, sig, &info);
3012} 3029}
3030#endif
3031#endif
3013 3032
3014long do_rt_tgsigqueueinfo(pid_t tgid, pid_t pid, int sig, siginfo_t *info) 3033long do_rt_tgsigqueueinfo(pid_t tgid, pid_t pid, int sig, siginfo_t *info)
3015{ 3034{