generic compat_sys_rt_sigqueueinfo()
conditional on GENERIC_COMPAT_RT_SIGQUEUEINFO; by the end of that series it will become the same thing as COMPAT and conditional will die out. Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
@@ -2983,6 +2983,22 @@ SYSCALL_DEFINE2(tkill, pid_t, pid, int, sig)
|
||||
return do_tkill(0, pid, sig);
|
||||
}
|
||||
|
||||
static int do_rt_sigqueueinfo(pid_t pid, int sig, siginfo_t *info)
|
||||
{
|
||||
/* Not even root can pretend to send signals from the kernel.
|
||||
* Nor can they impersonate a kill()/tgkill(), which adds source info.
|
||||
*/
|
||||
if (info->si_code >= 0 || info->si_code == SI_TKILL) {
|
||||
/* We used to allow any < 0 si_code */
|
||||
WARN_ON_ONCE(info->si_code < 0);
|
||||
return -EPERM;
|
||||
}
|
||||
info->si_signo = sig;
|
||||
|
||||
/* POSIX.1b doesn't mention process groups. */
|
||||
return kill_proc_info(sig, info, pid);
|
||||
}
|
||||
|
||||
/**
|
||||
* sys_rt_sigqueueinfo - send signal information to a signal
|
||||
* @pid: the PID of the thread
|
||||
@@ -2993,24 +3009,27 @@ SYSCALL_DEFINE3(rt_sigqueueinfo, pid_t, pid, int, sig,
|
||||
siginfo_t __user *, uinfo)
|
||||
{
|
||||
siginfo_t info;
|
||||
|
||||
if (copy_from_user(&info, uinfo, sizeof(siginfo_t)))
|
||||
return -EFAULT;
|
||||
|
||||
/* Not even root can pretend to send signals from the kernel.
|
||||
* Nor can they impersonate a kill()/tgkill(), which adds source info.
|
||||
*/
|
||||
if (info.si_code >= 0 || info.si_code == SI_TKILL) {
|
||||
/* We used to allow any < 0 si_code */
|
||||
WARN_ON_ONCE(info.si_code < 0);
|
||||
return -EPERM;
|
||||
}
|
||||
info.si_signo = sig;
|
||||
|
||||
/* POSIX.1b doesn't mention process groups. */
|
||||
return kill_proc_info(sig, &info, pid);
|
||||
return do_rt_sigqueueinfo(pid, sig, &info);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
#ifdef CONFIG_GENERIC_COMPAT_RT_SIGQUEUEINFO
|
||||
COMPAT_SYSCALL_DEFINE3(rt_sigqueueinfo,
|
||||
compat_pid_t, pid,
|
||||
int, sig,
|
||||
struct compat_siginfo __user *, uinfo)
|
||||
{
|
||||
siginfo_t info;
|
||||
int ret = copy_siginfo_from_user32(&info, uinfo);
|
||||
if (unlikely(ret))
|
||||
return ret;
|
||||
return do_rt_sigqueueinfo(pid, sig, &info);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
long do_rt_tgsigqueueinfo(pid_t tgid, pid_t pid, int sig, siginfo_t *info)
|
||||
{
|
||||
/* This is only valid for single tasks */
|
||||
|
Reference in New Issue
Block a user