|
|
|
@@ -1057,29 +1057,8 @@ static inline bool legacy_queue(struct sigpending *signals, int sig)
|
|
|
|
|
return (sig < SIGRTMIN) && sigismember(&signals->signal, sig);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef CONFIG_USER_NS
|
|
|
|
|
static inline void userns_fixup_signal_uid(struct kernel_siginfo *info, struct task_struct *t)
|
|
|
|
|
{
|
|
|
|
|
if (current_user_ns() == task_cred_xxx(t, user_ns))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
if (SI_FROMKERNEL(info))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
rcu_read_lock();
|
|
|
|
|
info->si_uid = from_kuid_munged(task_cred_xxx(t, user_ns),
|
|
|
|
|
make_kuid(current_user_ns(), info->si_uid));
|
|
|
|
|
rcu_read_unlock();
|
|
|
|
|
}
|
|
|
|
|
#else
|
|
|
|
|
static inline void userns_fixup_signal_uid(struct kernel_siginfo *info, struct task_struct *t)
|
|
|
|
|
{
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
static int __send_signal(int sig, struct kernel_siginfo *info, struct task_struct *t,
|
|
|
|
|
enum pid_type type, int from_ancestor_ns)
|
|
|
|
|
enum pid_type type, bool force)
|
|
|
|
|
{
|
|
|
|
|
struct sigpending *pending;
|
|
|
|
|
struct sigqueue *q;
|
|
|
|
@@ -1089,8 +1068,7 @@ static int __send_signal(int sig, struct kernel_siginfo *info, struct task_struc
|
|
|
|
|
assert_spin_locked(&t->sighand->siglock);
|
|
|
|
|
|
|
|
|
|
result = TRACE_SIGNAL_IGNORED;
|
|
|
|
|
if (!prepare_signal(sig, t,
|
|
|
|
|
from_ancestor_ns || (info == SEND_SIG_PRIV)))
|
|
|
|
|
if (!prepare_signal(sig, t, force))
|
|
|
|
|
goto ret;
|
|
|
|
|
|
|
|
|
|
pending = (type != PIDTYPE_PID) ? &t->signal->shared_pending : &t->pending;
|
|
|
|
@@ -1135,7 +1113,11 @@ static int __send_signal(int sig, struct kernel_siginfo *info, struct task_struc
|
|
|
|
|
q->info.si_code = SI_USER;
|
|
|
|
|
q->info.si_pid = task_tgid_nr_ns(current,
|
|
|
|
|
task_active_pid_ns(t));
|
|
|
|
|
q->info.si_uid = from_kuid_munged(current_user_ns(), current_uid());
|
|
|
|
|
rcu_read_lock();
|
|
|
|
|
q->info.si_uid =
|
|
|
|
|
from_kuid_munged(task_cred_xxx(t, user_ns),
|
|
|
|
|
current_uid());
|
|
|
|
|
rcu_read_unlock();
|
|
|
|
|
break;
|
|
|
|
|
case (unsigned long) SEND_SIG_PRIV:
|
|
|
|
|
clear_siginfo(&q->info);
|
|
|
|
@@ -1147,30 +1129,24 @@ static int __send_signal(int sig, struct kernel_siginfo *info, struct task_struc
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
copy_siginfo(&q->info, info);
|
|
|
|
|
if (from_ancestor_ns)
|
|
|
|
|
q->info.si_pid = 0;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
userns_fixup_signal_uid(&q->info, t);
|
|
|
|
|
|
|
|
|
|
} else if (!is_si_special(info)) {
|
|
|
|
|
if (sig >= SIGRTMIN && info->si_code != SI_USER) {
|
|
|
|
|
/*
|
|
|
|
|
* Queue overflow, abort. We may abort if the
|
|
|
|
|
* signal was rt and sent by user using something
|
|
|
|
|
* other than kill().
|
|
|
|
|
*/
|
|
|
|
|
result = TRACE_SIGNAL_OVERFLOW_FAIL;
|
|
|
|
|
ret = -EAGAIN;
|
|
|
|
|
goto ret;
|
|
|
|
|
} else {
|
|
|
|
|
/*
|
|
|
|
|
* This is a silent loss of information. We still
|
|
|
|
|
* send the signal, but the *info bits are lost.
|
|
|
|
|
*/
|
|
|
|
|
result = TRACE_SIGNAL_LOSE_INFO;
|
|
|
|
|
}
|
|
|
|
|
} else if (!is_si_special(info) &&
|
|
|
|
|
sig >= SIGRTMIN && info->si_code != SI_USER) {
|
|
|
|
|
/*
|
|
|
|
|
* Queue overflow, abort. We may abort if the
|
|
|
|
|
* signal was rt and sent by user using something
|
|
|
|
|
* other than kill().
|
|
|
|
|
*/
|
|
|
|
|
result = TRACE_SIGNAL_OVERFLOW_FAIL;
|
|
|
|
|
ret = -EAGAIN;
|
|
|
|
|
goto ret;
|
|
|
|
|
} else {
|
|
|
|
|
/*
|
|
|
|
|
* This is a silent loss of information. We still
|
|
|
|
|
* send the signal, but the *info bits are lost.
|
|
|
|
|
*/
|
|
|
|
|
result = TRACE_SIGNAL_LOSE_INFO;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
out_set:
|
|
|
|
@@ -1197,17 +1173,62 @@ ret:
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static inline bool has_si_pid_and_uid(struct kernel_siginfo *info)
|
|
|
|
|
{
|
|
|
|
|
bool ret = false;
|
|
|
|
|
switch (siginfo_layout(info->si_signo, info->si_code)) {
|
|
|
|
|
case SIL_KILL:
|
|
|
|
|
case SIL_CHLD:
|
|
|
|
|
case SIL_RT:
|
|
|
|
|
ret = true;
|
|
|
|
|
break;
|
|
|
|
|
case SIL_TIMER:
|
|
|
|
|
case SIL_POLL:
|
|
|
|
|
case SIL_FAULT:
|
|
|
|
|
case SIL_FAULT_MCEERR:
|
|
|
|
|
case SIL_FAULT_BNDERR:
|
|
|
|
|
case SIL_FAULT_PKUERR:
|
|
|
|
|
case SIL_SYS:
|
|
|
|
|
ret = false;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static int send_signal(int sig, struct kernel_siginfo *info, struct task_struct *t,
|
|
|
|
|
enum pid_type type)
|
|
|
|
|
{
|
|
|
|
|
int from_ancestor_ns = 0;
|
|
|
|
|
/* Should SIGKILL or SIGSTOP be received by a pid namespace init? */
|
|
|
|
|
bool force = false;
|
|
|
|
|
|
|
|
|
|
#ifdef CONFIG_PID_NS
|
|
|
|
|
from_ancestor_ns = si_fromuser(info) &&
|
|
|
|
|
!task_pid_nr_ns(current, task_active_pid_ns(t));
|
|
|
|
|
#endif
|
|
|
|
|
if (info == SEND_SIG_NOINFO) {
|
|
|
|
|
/* Force if sent from an ancestor pid namespace */
|
|
|
|
|
force = !task_pid_nr_ns(current, task_active_pid_ns(t));
|
|
|
|
|
} else if (info == SEND_SIG_PRIV) {
|
|
|
|
|
/* Don't ignore kernel generated signals */
|
|
|
|
|
force = true;
|
|
|
|
|
} else if (has_si_pid_and_uid(info)) {
|
|
|
|
|
/* SIGKILL and SIGSTOP is special or has ids */
|
|
|
|
|
struct user_namespace *t_user_ns;
|
|
|
|
|
|
|
|
|
|
return __send_signal(sig, info, t, type, from_ancestor_ns);
|
|
|
|
|
rcu_read_lock();
|
|
|
|
|
t_user_ns = task_cred_xxx(t, user_ns);
|
|
|
|
|
if (current_user_ns() != t_user_ns) {
|
|
|
|
|
kuid_t uid = make_kuid(current_user_ns(), info->si_uid);
|
|
|
|
|
info->si_uid = from_kuid_munged(t_user_ns, uid);
|
|
|
|
|
}
|
|
|
|
|
rcu_read_unlock();
|
|
|
|
|
|
|
|
|
|
/* A kernel generated signal? */
|
|
|
|
|
force = (info->si_code == SI_KERNEL);
|
|
|
|
|
|
|
|
|
|
/* From an ancestor pid namespace? */
|
|
|
|
|
if (!task_pid_nr_ns(current, task_active_pid_ns(t))) {
|
|
|
|
|
info->si_pid = 0;
|
|
|
|
|
force = true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return __send_signal(sig, info, t, type, force);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void print_fatal_signal(int signr)
|
|
|
|
@@ -1274,12 +1295,13 @@ int do_send_sig_info(int sig, struct kernel_siginfo *info, struct task_struct *p
|
|
|
|
|
* We don't want to have recursive SIGSEGV's etc, for example,
|
|
|
|
|
* that is why we also clear SIGNAL_UNKILLABLE.
|
|
|
|
|
*/
|
|
|
|
|
int
|
|
|
|
|
force_sig_info(int sig, struct kernel_siginfo *info, struct task_struct *t)
|
|
|
|
|
static int
|
|
|
|
|
force_sig_info_to_task(struct kernel_siginfo *info, struct task_struct *t)
|
|
|
|
|
{
|
|
|
|
|
unsigned long int flags;
|
|
|
|
|
int ret, blocked, ignored;
|
|
|
|
|
struct k_sigaction *action;
|
|
|
|
|
int sig = info->si_signo;
|
|
|
|
|
|
|
|
|
|
spin_lock_irqsave(&t->sighand->siglock, flags);
|
|
|
|
|
action = &t->sighand->action[sig-1];
|
|
|
|
@@ -1304,6 +1326,11 @@ force_sig_info(int sig, struct kernel_siginfo *info, struct task_struct *t)
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int force_sig_info(struct kernel_siginfo *info)
|
|
|
|
|
{
|
|
|
|
|
return force_sig_info_to_task(info, current);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Nuke all other threads in the group.
|
|
|
|
|
*/
|
|
|
|
@@ -1440,13 +1467,44 @@ static inline bool kill_as_cred_perm(const struct cred *cred,
|
|
|
|
|
uid_eq(cred->uid, pcred->uid);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* like kill_pid_info(), but doesn't use uid/euid of "current" */
|
|
|
|
|
int kill_pid_info_as_cred(int sig, struct kernel_siginfo *info, struct pid *pid,
|
|
|
|
|
const struct cred *cred)
|
|
|
|
|
/*
|
|
|
|
|
* The usb asyncio usage of siginfo is wrong. The glibc support
|
|
|
|
|
* for asyncio which uses SI_ASYNCIO assumes the layout is SIL_RT.
|
|
|
|
|
* AKA after the generic fields:
|
|
|
|
|
* kernel_pid_t si_pid;
|
|
|
|
|
* kernel_uid32_t si_uid;
|
|
|
|
|
* sigval_t si_value;
|
|
|
|
|
*
|
|
|
|
|
* Unfortunately when usb generates SI_ASYNCIO it assumes the layout
|
|
|
|
|
* after the generic fields is:
|
|
|
|
|
* void __user *si_addr;
|
|
|
|
|
*
|
|
|
|
|
* This is a practical problem when there is a 64bit big endian kernel
|
|
|
|
|
* and a 32bit userspace. As the 32bit address will encoded in the low
|
|
|
|
|
* 32bits of the pointer. Those low 32bits will be stored at higher
|
|
|
|
|
* address than appear in a 32 bit pointer. So userspace will not
|
|
|
|
|
* see the address it was expecting for it's completions.
|
|
|
|
|
*
|
|
|
|
|
* There is nothing in the encoding that can allow
|
|
|
|
|
* copy_siginfo_to_user32 to detect this confusion of formats, so
|
|
|
|
|
* handle this by requiring the caller of kill_pid_usb_asyncio to
|
|
|
|
|
* notice when this situration takes place and to store the 32bit
|
|
|
|
|
* pointer in sival_int, instead of sival_addr of the sigval_t addr
|
|
|
|
|
* parameter.
|
|
|
|
|
*/
|
|
|
|
|
int kill_pid_usb_asyncio(int sig, int errno, sigval_t addr,
|
|
|
|
|
struct pid *pid, const struct cred *cred)
|
|
|
|
|
{
|
|
|
|
|
int ret = -EINVAL;
|
|
|
|
|
struct kernel_siginfo info;
|
|
|
|
|
struct task_struct *p;
|
|
|
|
|
unsigned long flags;
|
|
|
|
|
int ret = -EINVAL;
|
|
|
|
|
|
|
|
|
|
clear_siginfo(&info);
|
|
|
|
|
info.si_signo = sig;
|
|
|
|
|
info.si_errno = errno;
|
|
|
|
|
info.si_code = SI_ASYNCIO;
|
|
|
|
|
*((sigval_t *)&info.si_pid) = addr;
|
|
|
|
|
|
|
|
|
|
if (!valid_signal(sig))
|
|
|
|
|
return ret;
|
|
|
|
@@ -1457,17 +1515,17 @@ int kill_pid_info_as_cred(int sig, struct kernel_siginfo *info, struct pid *pid,
|
|
|
|
|
ret = -ESRCH;
|
|
|
|
|
goto out_unlock;
|
|
|
|
|
}
|
|
|
|
|
if (si_fromuser(info) && !kill_as_cred_perm(cred, p)) {
|
|
|
|
|
if (!kill_as_cred_perm(cred, p)) {
|
|
|
|
|
ret = -EPERM;
|
|
|
|
|
goto out_unlock;
|
|
|
|
|
}
|
|
|
|
|
ret = security_task_kill(p, info, sig, cred);
|
|
|
|
|
ret = security_task_kill(p, &info, sig, cred);
|
|
|
|
|
if (ret)
|
|
|
|
|
goto out_unlock;
|
|
|
|
|
|
|
|
|
|
if (sig) {
|
|
|
|
|
if (lock_task_sighand(p, &flags)) {
|
|
|
|
|
ret = __send_signal(sig, info, p, PIDTYPE_TGID, 0);
|
|
|
|
|
ret = __send_signal(sig, &info, p, PIDTYPE_TGID, false);
|
|
|
|
|
unlock_task_sighand(p, &flags);
|
|
|
|
|
} else
|
|
|
|
|
ret = -ESRCH;
|
|
|
|
@@ -1476,7 +1534,7 @@ out_unlock:
|
|
|
|
|
rcu_read_unlock();
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
EXPORT_SYMBOL_GPL(kill_pid_info_as_cred);
|
|
|
|
|
EXPORT_SYMBOL_GPL(kill_pid_usb_asyncio);
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* kill_something_info() interprets pid in interesting ways just like kill(2).
|
|
|
|
@@ -1552,9 +1610,17 @@ send_sig(int sig, struct task_struct *p, int priv)
|
|
|
|
|
}
|
|
|
|
|
EXPORT_SYMBOL(send_sig);
|
|
|
|
|
|
|
|
|
|
void force_sig(int sig, struct task_struct *p)
|
|
|
|
|
void force_sig(int sig)
|
|
|
|
|
{
|
|
|
|
|
force_sig_info(sig, SEND_SIG_PRIV, p);
|
|
|
|
|
struct kernel_siginfo info;
|
|
|
|
|
|
|
|
|
|
clear_siginfo(&info);
|
|
|
|
|
info.si_signo = sig;
|
|
|
|
|
info.si_errno = 0;
|
|
|
|
|
info.si_code = SI_KERNEL;
|
|
|
|
|
info.si_pid = 0;
|
|
|
|
|
info.si_uid = 0;
|
|
|
|
|
force_sig_info(&info);
|
|
|
|
|
}
|
|
|
|
|
EXPORT_SYMBOL(force_sig);
|
|
|
|
|
|
|
|
|
@@ -1564,18 +1630,20 @@ EXPORT_SYMBOL(force_sig);
|
|
|
|
|
* the problem was already a SIGSEGV, we'll want to
|
|
|
|
|
* make sure we don't even try to deliver the signal..
|
|
|
|
|
*/
|
|
|
|
|
void force_sigsegv(int sig, struct task_struct *p)
|
|
|
|
|
void force_sigsegv(int sig)
|
|
|
|
|
{
|
|
|
|
|
struct task_struct *p = current;
|
|
|
|
|
|
|
|
|
|
if (sig == SIGSEGV) {
|
|
|
|
|
unsigned long flags;
|
|
|
|
|
spin_lock_irqsave(&p->sighand->siglock, flags);
|
|
|
|
|
p->sighand->action[sig - 1].sa.sa_handler = SIG_DFL;
|
|
|
|
|
spin_unlock_irqrestore(&p->sighand->siglock, flags);
|
|
|
|
|
}
|
|
|
|
|
force_sig(SIGSEGV, p);
|
|
|
|
|
force_sig(SIGSEGV);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int force_sig_fault(int sig, int code, void __user *addr
|
|
|
|
|
int force_sig_fault_to_task(int sig, int code, void __user *addr
|
|
|
|
|
___ARCH_SI_TRAPNO(int trapno)
|
|
|
|
|
___ARCH_SI_IA64(int imm, unsigned int flags, unsigned long isr)
|
|
|
|
|
, struct task_struct *t)
|
|
|
|
@@ -1595,7 +1663,16 @@ int force_sig_fault(int sig, int code, void __user *addr
|
|
|
|
|
info.si_flags = flags;
|
|
|
|
|
info.si_isr = isr;
|
|
|
|
|
#endif
|
|
|
|
|
return force_sig_info(info.si_signo, &info, t);
|
|
|
|
|
return force_sig_info_to_task(&info, t);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int force_sig_fault(int sig, int code, void __user *addr
|
|
|
|
|
___ARCH_SI_TRAPNO(int trapno)
|
|
|
|
|
___ARCH_SI_IA64(int imm, unsigned int flags, unsigned long isr))
|
|
|
|
|
{
|
|
|
|
|
return force_sig_fault_to_task(sig, code, addr
|
|
|
|
|
___ARCH_SI_TRAPNO(trapno)
|
|
|
|
|
___ARCH_SI_IA64(imm, flags, isr), current);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int send_sig_fault(int sig, int code, void __user *addr
|
|
|
|
@@ -1621,7 +1698,7 @@ int send_sig_fault(int sig, int code, void __user *addr
|
|
|
|
|
return send_sig_info(info.si_signo, &info, t);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int force_sig_mceerr(int code, void __user *addr, short lsb, struct task_struct *t)
|
|
|
|
|
int force_sig_mceerr(int code, void __user *addr, short lsb)
|
|
|
|
|
{
|
|
|
|
|
struct kernel_siginfo info;
|
|
|
|
|
|
|
|
|
@@ -1632,7 +1709,7 @@ int force_sig_mceerr(int code, void __user *addr, short lsb, struct task_struct
|
|
|
|
|
info.si_code = code;
|
|
|
|
|
info.si_addr = addr;
|
|
|
|
|
info.si_addr_lsb = lsb;
|
|
|
|
|
return force_sig_info(info.si_signo, &info, t);
|
|
|
|
|
return force_sig_info(&info);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int send_sig_mceerr(int code, void __user *addr, short lsb, struct task_struct *t)
|
|
|
|
@@ -1661,7 +1738,7 @@ int force_sig_bnderr(void __user *addr, void __user *lower, void __user *upper)
|
|
|
|
|
info.si_addr = addr;
|
|
|
|
|
info.si_lower = lower;
|
|
|
|
|
info.si_upper = upper;
|
|
|
|
|
return force_sig_info(info.si_signo, &info, current);
|
|
|
|
|
return force_sig_info(&info);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#ifdef SEGV_PKUERR
|
|
|
|
@@ -1675,7 +1752,7 @@ int force_sig_pkuerr(void __user *addr, u32 pkey)
|
|
|
|
|
info.si_code = SEGV_PKUERR;
|
|
|
|
|
info.si_addr = addr;
|
|
|
|
|
info.si_pkey = pkey;
|
|
|
|
|
return force_sig_info(info.si_signo, &info, current);
|
|
|
|
|
return force_sig_info(&info);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
@@ -1691,7 +1768,7 @@ int force_sig_ptrace_errno_trap(int errno, void __user *addr)
|
|
|
|
|
info.si_errno = errno;
|
|
|
|
|
info.si_code = TRAP_HWBKPT;
|
|
|
|
|
info.si_addr = addr;
|
|
|
|
|
return force_sig_info(info.si_signo, &info, current);
|
|
|
|
|
return force_sig_info(&info);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int kill_pgrp(struct pid *pid, int sig, int priv)
|
|
|
|
@@ -2676,7 +2753,7 @@ static void signal_delivered(struct ksignal *ksig, int stepping)
|
|
|
|
|
void signal_setup_done(int failed, struct ksignal *ksig, int stepping)
|
|
|
|
|
{
|
|
|
|
|
if (failed)
|
|
|
|
|
force_sigsegv(ksig->sig, current);
|
|
|
|
|
force_sigsegv(ksig->sig);
|
|
|
|
|
else
|
|
|
|
|
signal_delivered(ksig, stepping);
|
|
|
|
|
}
|
|
|
|
@@ -4477,6 +4554,28 @@ static inline void siginfo_buildtime_checks(void)
|
|
|
|
|
CHECK_OFFSET(si_syscall);
|
|
|
|
|
CHECK_OFFSET(si_arch);
|
|
|
|
|
#undef CHECK_OFFSET
|
|
|
|
|
|
|
|
|
|
/* usb asyncio */
|
|
|
|
|
BUILD_BUG_ON(offsetof(struct siginfo, si_pid) !=
|
|
|
|
|
offsetof(struct siginfo, si_addr));
|
|
|
|
|
if (sizeof(int) == sizeof(void __user *)) {
|
|
|
|
|
BUILD_BUG_ON(sizeof_field(struct siginfo, si_pid) !=
|
|
|
|
|
sizeof(void __user *));
|
|
|
|
|
} else {
|
|
|
|
|
BUILD_BUG_ON((sizeof_field(struct siginfo, si_pid) +
|
|
|
|
|
sizeof_field(struct siginfo, si_uid)) !=
|
|
|
|
|
sizeof(void __user *));
|
|
|
|
|
BUILD_BUG_ON(offsetofend(struct siginfo, si_pid) !=
|
|
|
|
|
offsetof(struct siginfo, si_uid));
|
|
|
|
|
}
|
|
|
|
|
#ifdef CONFIG_COMPAT
|
|
|
|
|
BUILD_BUG_ON(offsetof(struct compat_siginfo, si_pid) !=
|
|
|
|
|
offsetof(struct compat_siginfo, si_addr));
|
|
|
|
|
BUILD_BUG_ON(sizeof_field(struct compat_siginfo, si_pid) !=
|
|
|
|
|
sizeof(compat_uptr_t));
|
|
|
|
|
BUILD_BUG_ON(sizeof_field(struct compat_siginfo, si_pid) !=
|
|
|
|
|
sizeof_field(struct siginfo, si_pid));
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void __init signals_init(void)
|
|
|
|
|