forked from Minki/linux
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:
parent
fe9c1db2cf
commit
75907d4d7b
@ -365,6 +365,9 @@ config GENERIC_COMPAT_RT_SIGPROCMASK
|
||||
config GENERIC_COMPAT_RT_SIGPENDING
|
||||
bool
|
||||
|
||||
config GENERIC_COMPAT_RT_SIGQUEUEINFO
|
||||
bool
|
||||
|
||||
#
|
||||
# ABI hall of shame
|
||||
#
|
||||
|
@ -602,6 +602,10 @@ asmlinkage long compat_sys_rt_sigprocmask(int how, compat_sigset_t __user *set,
|
||||
asmlinkage long compat_sys_rt_sigpending(compat_sigset_t __user *uset,
|
||||
compat_size_t sigsetsize);
|
||||
#endif
|
||||
#ifdef CONFIG_GENERIC_COMPAT_RT_SIGQUEUEINFO
|
||||
asmlinkage long compat_sys_rt_sigqueueinfo(compat_pid_t pid, int sig,
|
||||
struct compat_siginfo __user *uinfo);
|
||||
#endif
|
||||
asmlinkage long compat_sys_sysinfo(struct compat_sysinfo __user *info);
|
||||
asmlinkage long compat_sys_ioctl(unsigned int fd, unsigned int cmd,
|
||||
unsigned long arg);
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user