mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2025-01-24 09:13:20 -05:00
Merge branch 'for-v5.13-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace
Pull siginfo fix from Eric Biederman: "During the merge window an issue with si_perf and the siginfo ABI came up. The alpha and sparc siginfo structure layout had changed with the addition of SIGTRAP TRAP_PERF and the new field si_perf. The reason only alpha and sparc were affected is that they are the only architectures that use si_trapno. Looking deeper it was discovered that si_trapno is used for only a few select signals on alpha and sparc, and that none of the other _sigfault fields past si_addr are used at all. Which means technically no regression on alpha and sparc. While the alignment concerns might be dismissed the abuse of si_errno by SIGTRAP TRAP_PERF does have the potential to cause regressions in existing userspace. While we still have time before userspace starts using and depending on the new definition siginfo for SIGTRAP TRAP_PERF this set of changes cleans up siginfo_t. - The si_trapno field is demoted from magic alpha and sparc status and made an ordinary union member of the _sigfault member of siginfo_t. Without moving it of course. - si_perf is replaced with si_perf_data and si_perf_type ending the abuse of si_errno. - Unnecessary additions to signalfd_siginfo are removed" * 'for-v5.13-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace: signalfd: Remove SIL_PERF_EVENT fields from signalfd_siginfo signal: Deliver all of the siginfo perf data in _perf signal: Factor force_sig_perf out of perf_sigtrap signal: Implement SIL_FAULT_TRAPNO siginfo: Move si_trapno inside the union inside _si_fault
This commit is contained in:
commit
a0e31f3a38
12 changed files with 79 additions and 73 deletions
|
@ -623,7 +623,8 @@ static inline void siginfo_build_tests(void)
|
||||||
BUILD_BUG_ON(offsetof(siginfo_t, si_pkey) != 0x12);
|
BUILD_BUG_ON(offsetof(siginfo_t, si_pkey) != 0x12);
|
||||||
|
|
||||||
/* _sigfault._perf */
|
/* _sigfault._perf */
|
||||||
BUILD_BUG_ON(offsetof(siginfo_t, si_perf) != 0x10);
|
BUILD_BUG_ON(offsetof(siginfo_t, si_perf_data) != 0x10);
|
||||||
|
BUILD_BUG_ON(offsetof(siginfo_t, si_perf_type) != 0x14);
|
||||||
|
|
||||||
/* _sigpoll */
|
/* _sigpoll */
|
||||||
BUILD_BUG_ON(offsetof(siginfo_t, si_band) != 0x0c);
|
BUILD_BUG_ON(offsetof(siginfo_t, si_band) != 0x0c);
|
||||||
|
|
|
@ -127,6 +127,9 @@ static inline void signal_compat_build_tests(void)
|
||||||
BUILD_BUG_ON(offsetof(siginfo_t, si_addr) != 0x10);
|
BUILD_BUG_ON(offsetof(siginfo_t, si_addr) != 0x10);
|
||||||
BUILD_BUG_ON(offsetof(compat_siginfo_t, si_addr) != 0x0C);
|
BUILD_BUG_ON(offsetof(compat_siginfo_t, si_addr) != 0x0C);
|
||||||
|
|
||||||
|
BUILD_BUG_ON(offsetof(siginfo_t, si_trapno) != 0x18);
|
||||||
|
BUILD_BUG_ON(offsetof(compat_siginfo_t, si_trapno) != 0x10);
|
||||||
|
|
||||||
BUILD_BUG_ON(offsetof(siginfo_t, si_addr_lsb) != 0x18);
|
BUILD_BUG_ON(offsetof(siginfo_t, si_addr_lsb) != 0x18);
|
||||||
BUILD_BUG_ON(offsetof(compat_siginfo_t, si_addr_lsb) != 0x10);
|
BUILD_BUG_ON(offsetof(compat_siginfo_t, si_addr_lsb) != 0x10);
|
||||||
|
|
||||||
|
@ -138,8 +141,10 @@ static inline void signal_compat_build_tests(void)
|
||||||
BUILD_BUG_ON(offsetof(siginfo_t, si_pkey) != 0x20);
|
BUILD_BUG_ON(offsetof(siginfo_t, si_pkey) != 0x20);
|
||||||
BUILD_BUG_ON(offsetof(compat_siginfo_t, si_pkey) != 0x14);
|
BUILD_BUG_ON(offsetof(compat_siginfo_t, si_pkey) != 0x14);
|
||||||
|
|
||||||
BUILD_BUG_ON(offsetof(siginfo_t, si_perf) != 0x18);
|
BUILD_BUG_ON(offsetof(siginfo_t, si_perf_data) != 0x18);
|
||||||
BUILD_BUG_ON(offsetof(compat_siginfo_t, si_perf) != 0x10);
|
BUILD_BUG_ON(offsetof(siginfo_t, si_perf_type) != 0x20);
|
||||||
|
BUILD_BUG_ON(offsetof(compat_siginfo_t, si_perf_data) != 0x10);
|
||||||
|
BUILD_BUG_ON(offsetof(compat_siginfo_t, si_perf_type) != 0x14);
|
||||||
|
|
||||||
CHECK_CSI_OFFSET(_sigpoll);
|
CHECK_CSI_OFFSET(_sigpoll);
|
||||||
CHECK_CSI_SIZE (_sigpoll, 2*sizeof(int));
|
CHECK_CSI_SIZE (_sigpoll, 2*sizeof(int));
|
||||||
|
|
|
@ -114,30 +114,25 @@ static int signalfd_copyinfo(struct signalfd_siginfo __user *uinfo,
|
||||||
break;
|
break;
|
||||||
case SIL_FAULT_BNDERR:
|
case SIL_FAULT_BNDERR:
|
||||||
case SIL_FAULT_PKUERR:
|
case SIL_FAULT_PKUERR:
|
||||||
|
case SIL_PERF_EVENT:
|
||||||
/*
|
/*
|
||||||
* Fall through to the SIL_FAULT case. Both SIL_FAULT_BNDERR
|
* Fall through to the SIL_FAULT case. SIL_FAULT_BNDERR,
|
||||||
* and SIL_FAULT_PKUERR are only generated by faults that
|
* SIL_FAULT_PKUERR, and SIL_PERF_EVENT are only
|
||||||
* deliver them synchronously to userspace. In case someone
|
* generated by faults that deliver them synchronously to
|
||||||
* injects one of these signals and signalfd catches it treat
|
* userspace. In case someone injects one of these signals
|
||||||
* it as SIL_FAULT.
|
* and signalfd catches it treat it as SIL_FAULT.
|
||||||
*/
|
*/
|
||||||
case SIL_FAULT:
|
case SIL_FAULT:
|
||||||
new.ssi_addr = (long) kinfo->si_addr;
|
new.ssi_addr = (long) kinfo->si_addr;
|
||||||
#ifdef __ARCH_SI_TRAPNO
|
break;
|
||||||
|
case SIL_FAULT_TRAPNO:
|
||||||
|
new.ssi_addr = (long) kinfo->si_addr;
|
||||||
new.ssi_trapno = kinfo->si_trapno;
|
new.ssi_trapno = kinfo->si_trapno;
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
case SIL_FAULT_MCEERR:
|
case SIL_FAULT_MCEERR:
|
||||||
new.ssi_addr = (long) kinfo->si_addr;
|
new.ssi_addr = (long) kinfo->si_addr;
|
||||||
#ifdef __ARCH_SI_TRAPNO
|
|
||||||
new.ssi_trapno = kinfo->si_trapno;
|
|
||||||
#endif
|
|
||||||
new.ssi_addr_lsb = (short) kinfo->si_addr_lsb;
|
new.ssi_addr_lsb = (short) kinfo->si_addr_lsb;
|
||||||
break;
|
break;
|
||||||
case SIL_PERF_EVENT:
|
|
||||||
new.ssi_addr = (long) kinfo->si_addr;
|
|
||||||
new.ssi_perf = kinfo->si_perf;
|
|
||||||
break;
|
|
||||||
case SIL_CHLD:
|
case SIL_CHLD:
|
||||||
new.ssi_pid = kinfo->si_pid;
|
new.ssi_pid = kinfo->si_pid;
|
||||||
new.ssi_uid = kinfo->si_uid;
|
new.ssi_uid = kinfo->si_uid;
|
||||||
|
|
|
@ -213,12 +213,11 @@ typedef struct compat_siginfo {
|
||||||
/* SIGILL, SIGFPE, SIGSEGV, SIGBUS, SIGTRAP, SIGEMT */
|
/* SIGILL, SIGFPE, SIGSEGV, SIGBUS, SIGTRAP, SIGEMT */
|
||||||
struct {
|
struct {
|
||||||
compat_uptr_t _addr; /* faulting insn/memory ref. */
|
compat_uptr_t _addr; /* faulting insn/memory ref. */
|
||||||
#ifdef __ARCH_SI_TRAPNO
|
|
||||||
int _trapno; /* TRAP # which caused the signal */
|
|
||||||
#endif
|
|
||||||
#define __COMPAT_ADDR_BND_PKEY_PAD (__alignof__(compat_uptr_t) < sizeof(short) ? \
|
#define __COMPAT_ADDR_BND_PKEY_PAD (__alignof__(compat_uptr_t) < sizeof(short) ? \
|
||||||
sizeof(short) : __alignof__(compat_uptr_t))
|
sizeof(short) : __alignof__(compat_uptr_t))
|
||||||
union {
|
union {
|
||||||
|
/* used on alpha and sparc */
|
||||||
|
int _trapno; /* TRAP # which caused the signal */
|
||||||
/*
|
/*
|
||||||
* used when si_code=BUS_MCEERR_AR or
|
* used when si_code=BUS_MCEERR_AR or
|
||||||
* used when si_code=BUS_MCEERR_AO
|
* used when si_code=BUS_MCEERR_AO
|
||||||
|
@ -236,7 +235,10 @@ typedef struct compat_siginfo {
|
||||||
u32 _pkey;
|
u32 _pkey;
|
||||||
} _addr_pkey;
|
} _addr_pkey;
|
||||||
/* used when si_code=TRAP_PERF */
|
/* used when si_code=TRAP_PERF */
|
||||||
compat_ulong_t _perf;
|
struct {
|
||||||
|
compat_ulong_t _data;
|
||||||
|
u32 _type;
|
||||||
|
} _perf;
|
||||||
};
|
};
|
||||||
} _sigfault;
|
} _sigfault;
|
||||||
|
|
||||||
|
|
|
@ -326,6 +326,7 @@ int send_sig_mceerr(int code, void __user *, short, struct task_struct *);
|
||||||
|
|
||||||
int force_sig_bnderr(void __user *addr, void __user *lower, void __user *upper);
|
int force_sig_bnderr(void __user *addr, void __user *lower, void __user *upper);
|
||||||
int force_sig_pkuerr(void __user *addr, u32 pkey);
|
int force_sig_pkuerr(void __user *addr, u32 pkey);
|
||||||
|
int force_sig_perf(void __user *addr, u32 type, u64 sig_data);
|
||||||
|
|
||||||
int force_sig_ptrace_errno_trap(int errno, void __user *addr);
|
int force_sig_ptrace_errno_trap(int errno, void __user *addr);
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,7 @@ enum siginfo_layout {
|
||||||
SIL_TIMER,
|
SIL_TIMER,
|
||||||
SIL_POLL,
|
SIL_POLL,
|
||||||
SIL_FAULT,
|
SIL_FAULT,
|
||||||
|
SIL_FAULT_TRAPNO,
|
||||||
SIL_FAULT_MCEERR,
|
SIL_FAULT_MCEERR,
|
||||||
SIL_FAULT_BNDERR,
|
SIL_FAULT_BNDERR,
|
||||||
SIL_FAULT_PKUERR,
|
SIL_FAULT_PKUERR,
|
||||||
|
|
|
@ -63,9 +63,6 @@ union __sifields {
|
||||||
/* SIGILL, SIGFPE, SIGSEGV, SIGBUS, SIGTRAP, SIGEMT */
|
/* SIGILL, SIGFPE, SIGSEGV, SIGBUS, SIGTRAP, SIGEMT */
|
||||||
struct {
|
struct {
|
||||||
void __user *_addr; /* faulting insn/memory ref. */
|
void __user *_addr; /* faulting insn/memory ref. */
|
||||||
#ifdef __ARCH_SI_TRAPNO
|
|
||||||
int _trapno; /* TRAP # which caused the signal */
|
|
||||||
#endif
|
|
||||||
#ifdef __ia64__
|
#ifdef __ia64__
|
||||||
int _imm; /* immediate value for "break" */
|
int _imm; /* immediate value for "break" */
|
||||||
unsigned int _flags; /* see ia64 si_flags */
|
unsigned int _flags; /* see ia64 si_flags */
|
||||||
|
@ -75,6 +72,8 @@ union __sifields {
|
||||||
#define __ADDR_BND_PKEY_PAD (__alignof__(void *) < sizeof(short) ? \
|
#define __ADDR_BND_PKEY_PAD (__alignof__(void *) < sizeof(short) ? \
|
||||||
sizeof(short) : __alignof__(void *))
|
sizeof(short) : __alignof__(void *))
|
||||||
union {
|
union {
|
||||||
|
/* used on alpha and sparc */
|
||||||
|
int _trapno; /* TRAP # which caused the signal */
|
||||||
/*
|
/*
|
||||||
* used when si_code=BUS_MCEERR_AR or
|
* used when si_code=BUS_MCEERR_AR or
|
||||||
* used when si_code=BUS_MCEERR_AO
|
* used when si_code=BUS_MCEERR_AO
|
||||||
|
@ -92,7 +91,10 @@ union __sifields {
|
||||||
__u32 _pkey;
|
__u32 _pkey;
|
||||||
} _addr_pkey;
|
} _addr_pkey;
|
||||||
/* used when si_code=TRAP_PERF */
|
/* used when si_code=TRAP_PERF */
|
||||||
unsigned long _perf;
|
struct {
|
||||||
|
unsigned long _data;
|
||||||
|
__u32 _type;
|
||||||
|
} _perf;
|
||||||
};
|
};
|
||||||
} _sigfault;
|
} _sigfault;
|
||||||
|
|
||||||
|
@ -150,14 +152,13 @@ typedef struct siginfo {
|
||||||
#define si_int _sifields._rt._sigval.sival_int
|
#define si_int _sifields._rt._sigval.sival_int
|
||||||
#define si_ptr _sifields._rt._sigval.sival_ptr
|
#define si_ptr _sifields._rt._sigval.sival_ptr
|
||||||
#define si_addr _sifields._sigfault._addr
|
#define si_addr _sifields._sigfault._addr
|
||||||
#ifdef __ARCH_SI_TRAPNO
|
|
||||||
#define si_trapno _sifields._sigfault._trapno
|
#define si_trapno _sifields._sigfault._trapno
|
||||||
#endif
|
|
||||||
#define si_addr_lsb _sifields._sigfault._addr_lsb
|
#define si_addr_lsb _sifields._sigfault._addr_lsb
|
||||||
#define si_lower _sifields._sigfault._addr_bnd._lower
|
#define si_lower _sifields._sigfault._addr_bnd._lower
|
||||||
#define si_upper _sifields._sigfault._addr_bnd._upper
|
#define si_upper _sifields._sigfault._addr_bnd._upper
|
||||||
#define si_pkey _sifields._sigfault._addr_pkey._pkey
|
#define si_pkey _sifields._sigfault._addr_pkey._pkey
|
||||||
#define si_perf _sifields._sigfault._perf
|
#define si_perf_data _sifields._sigfault._perf._data
|
||||||
|
#define si_perf_type _sifields._sigfault._perf._type
|
||||||
#define si_band _sifields._sigpoll._band
|
#define si_band _sifields._sigpoll._band
|
||||||
#define si_fd _sifields._sigpoll._fd
|
#define si_fd _sifields._sigpoll._fd
|
||||||
#define si_call_addr _sifields._sigsys._call_addr
|
#define si_call_addr _sifields._sigsys._call_addr
|
||||||
|
|
|
@ -464,7 +464,7 @@ struct perf_event_attr {
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* User provided data if sigtrap=1, passed back to user via
|
* User provided data if sigtrap=1, passed back to user via
|
||||||
* siginfo_t::si_perf, e.g. to permit user to identify the event.
|
* siginfo_t::si_perf_data, e.g. to permit user to identify the event.
|
||||||
*/
|
*/
|
||||||
__u64 sig_data;
|
__u64 sig_data;
|
||||||
};
|
};
|
||||||
|
|
|
@ -39,8 +39,6 @@ struct signalfd_siginfo {
|
||||||
__s32 ssi_syscall;
|
__s32 ssi_syscall;
|
||||||
__u64 ssi_call_addr;
|
__u64 ssi_call_addr;
|
||||||
__u32 ssi_arch;
|
__u32 ssi_arch;
|
||||||
__u32 __pad3;
|
|
||||||
__u64 ssi_perf;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Pad strcture to 128 bytes. Remember to update the
|
* Pad strcture to 128 bytes. Remember to update the
|
||||||
|
@ -51,7 +49,7 @@ struct signalfd_siginfo {
|
||||||
* comes out of a read(2) and we really don't want to have
|
* comes out of a read(2) and we really don't want to have
|
||||||
* a compat on read(2).
|
* a compat on read(2).
|
||||||
*/
|
*/
|
||||||
__u8 __pad[16];
|
__u8 __pad[28];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -6389,8 +6389,6 @@ void perf_event_wakeup(struct perf_event *event)
|
||||||
|
|
||||||
static void perf_sigtrap(struct perf_event *event)
|
static void perf_sigtrap(struct perf_event *event)
|
||||||
{
|
{
|
||||||
struct kernel_siginfo info;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We'd expect this to only occur if the irq_work is delayed and either
|
* We'd expect this to only occur if the irq_work is delayed and either
|
||||||
* ctx->task or current has changed in the meantime. This can be the
|
* ctx->task or current has changed in the meantime. This can be the
|
||||||
|
@ -6405,13 +6403,8 @@ static void perf_sigtrap(struct perf_event *event)
|
||||||
if (current->flags & PF_EXITING)
|
if (current->flags & PF_EXITING)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
clear_siginfo(&info);
|
force_sig_perf((void __user *)event->pending_addr,
|
||||||
info.si_signo = SIGTRAP;
|
event->attr.type, event->attr.sig_data);
|
||||||
info.si_code = TRAP_PERF;
|
|
||||||
info.si_errno = event->attr.type;
|
|
||||||
info.si_perf = event->attr.sig_data;
|
|
||||||
info.si_addr = (void __user *)event->pending_addr;
|
|
||||||
force_sig_info(&info);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void perf_pending_event_disable(struct perf_event *event)
|
static void perf_pending_event_disable(struct perf_event *event)
|
||||||
|
|
|
@ -1236,6 +1236,7 @@ static inline bool has_si_pid_and_uid(struct kernel_siginfo *info)
|
||||||
case SIL_TIMER:
|
case SIL_TIMER:
|
||||||
case SIL_POLL:
|
case SIL_POLL:
|
||||||
case SIL_FAULT:
|
case SIL_FAULT:
|
||||||
|
case SIL_FAULT_TRAPNO:
|
||||||
case SIL_FAULT_MCEERR:
|
case SIL_FAULT_MCEERR:
|
||||||
case SIL_FAULT_BNDERR:
|
case SIL_FAULT_BNDERR:
|
||||||
case SIL_FAULT_PKUERR:
|
case SIL_FAULT_PKUERR:
|
||||||
|
@ -1804,6 +1805,21 @@ int force_sig_pkuerr(void __user *addr, u32 pkey)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
int force_sig_perf(void __user *addr, u32 type, u64 sig_data)
|
||||||
|
{
|
||||||
|
struct kernel_siginfo info;
|
||||||
|
|
||||||
|
clear_siginfo(&info);
|
||||||
|
info.si_signo = SIGTRAP;
|
||||||
|
info.si_errno = 0;
|
||||||
|
info.si_code = TRAP_PERF;
|
||||||
|
info.si_addr = addr;
|
||||||
|
info.si_perf_data = sig_data;
|
||||||
|
info.si_perf_type = type;
|
||||||
|
|
||||||
|
return force_sig_info(&info);
|
||||||
|
}
|
||||||
|
|
||||||
/* For the crazy architectures that include trap information in
|
/* For the crazy architectures that include trap information in
|
||||||
* the errno field, instead of an actual errno value.
|
* the errno field, instead of an actual errno value.
|
||||||
*/
|
*/
|
||||||
|
@ -2564,6 +2580,7 @@ static void hide_si_addr_tag_bits(struct ksignal *ksig)
|
||||||
{
|
{
|
||||||
switch (siginfo_layout(ksig->sig, ksig->info.si_code)) {
|
switch (siginfo_layout(ksig->sig, ksig->info.si_code)) {
|
||||||
case SIL_FAULT:
|
case SIL_FAULT:
|
||||||
|
case SIL_FAULT_TRAPNO:
|
||||||
case SIL_FAULT_MCEERR:
|
case SIL_FAULT_MCEERR:
|
||||||
case SIL_FAULT_BNDERR:
|
case SIL_FAULT_BNDERR:
|
||||||
case SIL_FAULT_PKUERR:
|
case SIL_FAULT_PKUERR:
|
||||||
|
@ -3251,6 +3268,10 @@ enum siginfo_layout siginfo_layout(unsigned sig, int si_code)
|
||||||
#endif
|
#endif
|
||||||
else if ((sig == SIGTRAP) && (si_code == TRAP_PERF))
|
else if ((sig == SIGTRAP) && (si_code == TRAP_PERF))
|
||||||
layout = SIL_PERF_EVENT;
|
layout = SIL_PERF_EVENT;
|
||||||
|
#ifdef __ARCH_SI_TRAPNO
|
||||||
|
else if (layout == SIL_FAULT)
|
||||||
|
layout = SIL_FAULT_TRAPNO;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else if (si_code <= NSIGPOLL)
|
else if (si_code <= NSIGPOLL)
|
||||||
layout = SIL_POLL;
|
layout = SIL_POLL;
|
||||||
|
@ -3354,35 +3375,28 @@ void copy_siginfo_to_external32(struct compat_siginfo *to,
|
||||||
break;
|
break;
|
||||||
case SIL_FAULT:
|
case SIL_FAULT:
|
||||||
to->si_addr = ptr_to_compat(from->si_addr);
|
to->si_addr = ptr_to_compat(from->si_addr);
|
||||||
#ifdef __ARCH_SI_TRAPNO
|
break;
|
||||||
|
case SIL_FAULT_TRAPNO:
|
||||||
|
to->si_addr = ptr_to_compat(from->si_addr);
|
||||||
to->si_trapno = from->si_trapno;
|
to->si_trapno = from->si_trapno;
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
case SIL_FAULT_MCEERR:
|
case SIL_FAULT_MCEERR:
|
||||||
to->si_addr = ptr_to_compat(from->si_addr);
|
to->si_addr = ptr_to_compat(from->si_addr);
|
||||||
#ifdef __ARCH_SI_TRAPNO
|
|
||||||
to->si_trapno = from->si_trapno;
|
|
||||||
#endif
|
|
||||||
to->si_addr_lsb = from->si_addr_lsb;
|
to->si_addr_lsb = from->si_addr_lsb;
|
||||||
break;
|
break;
|
||||||
case SIL_FAULT_BNDERR:
|
case SIL_FAULT_BNDERR:
|
||||||
to->si_addr = ptr_to_compat(from->si_addr);
|
to->si_addr = ptr_to_compat(from->si_addr);
|
||||||
#ifdef __ARCH_SI_TRAPNO
|
|
||||||
to->si_trapno = from->si_trapno;
|
|
||||||
#endif
|
|
||||||
to->si_lower = ptr_to_compat(from->si_lower);
|
to->si_lower = ptr_to_compat(from->si_lower);
|
||||||
to->si_upper = ptr_to_compat(from->si_upper);
|
to->si_upper = ptr_to_compat(from->si_upper);
|
||||||
break;
|
break;
|
||||||
case SIL_FAULT_PKUERR:
|
case SIL_FAULT_PKUERR:
|
||||||
to->si_addr = ptr_to_compat(from->si_addr);
|
to->si_addr = ptr_to_compat(from->si_addr);
|
||||||
#ifdef __ARCH_SI_TRAPNO
|
|
||||||
to->si_trapno = from->si_trapno;
|
|
||||||
#endif
|
|
||||||
to->si_pkey = from->si_pkey;
|
to->si_pkey = from->si_pkey;
|
||||||
break;
|
break;
|
||||||
case SIL_PERF_EVENT:
|
case SIL_PERF_EVENT:
|
||||||
to->si_addr = ptr_to_compat(from->si_addr);
|
to->si_addr = ptr_to_compat(from->si_addr);
|
||||||
to->si_perf = from->si_perf;
|
to->si_perf_data = from->si_perf_data;
|
||||||
|
to->si_perf_type = from->si_perf_type;
|
||||||
break;
|
break;
|
||||||
case SIL_CHLD:
|
case SIL_CHLD:
|
||||||
to->si_pid = from->si_pid;
|
to->si_pid = from->si_pid;
|
||||||
|
@ -3438,35 +3452,28 @@ static int post_copy_siginfo_from_user32(kernel_siginfo_t *to,
|
||||||
break;
|
break;
|
||||||
case SIL_FAULT:
|
case SIL_FAULT:
|
||||||
to->si_addr = compat_ptr(from->si_addr);
|
to->si_addr = compat_ptr(from->si_addr);
|
||||||
#ifdef __ARCH_SI_TRAPNO
|
break;
|
||||||
|
case SIL_FAULT_TRAPNO:
|
||||||
|
to->si_addr = compat_ptr(from->si_addr);
|
||||||
to->si_trapno = from->si_trapno;
|
to->si_trapno = from->si_trapno;
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
case SIL_FAULT_MCEERR:
|
case SIL_FAULT_MCEERR:
|
||||||
to->si_addr = compat_ptr(from->si_addr);
|
to->si_addr = compat_ptr(from->si_addr);
|
||||||
#ifdef __ARCH_SI_TRAPNO
|
|
||||||
to->si_trapno = from->si_trapno;
|
|
||||||
#endif
|
|
||||||
to->si_addr_lsb = from->si_addr_lsb;
|
to->si_addr_lsb = from->si_addr_lsb;
|
||||||
break;
|
break;
|
||||||
case SIL_FAULT_BNDERR:
|
case SIL_FAULT_BNDERR:
|
||||||
to->si_addr = compat_ptr(from->si_addr);
|
to->si_addr = compat_ptr(from->si_addr);
|
||||||
#ifdef __ARCH_SI_TRAPNO
|
|
||||||
to->si_trapno = from->si_trapno;
|
|
||||||
#endif
|
|
||||||
to->si_lower = compat_ptr(from->si_lower);
|
to->si_lower = compat_ptr(from->si_lower);
|
||||||
to->si_upper = compat_ptr(from->si_upper);
|
to->si_upper = compat_ptr(from->si_upper);
|
||||||
break;
|
break;
|
||||||
case SIL_FAULT_PKUERR:
|
case SIL_FAULT_PKUERR:
|
||||||
to->si_addr = compat_ptr(from->si_addr);
|
to->si_addr = compat_ptr(from->si_addr);
|
||||||
#ifdef __ARCH_SI_TRAPNO
|
|
||||||
to->si_trapno = from->si_trapno;
|
|
||||||
#endif
|
|
||||||
to->si_pkey = from->si_pkey;
|
to->si_pkey = from->si_pkey;
|
||||||
break;
|
break;
|
||||||
case SIL_PERF_EVENT:
|
case SIL_PERF_EVENT:
|
||||||
to->si_addr = compat_ptr(from->si_addr);
|
to->si_addr = compat_ptr(from->si_addr);
|
||||||
to->si_perf = from->si_perf;
|
to->si_perf_data = from->si_perf_data;
|
||||||
|
to->si_perf_type = from->si_perf_type;
|
||||||
break;
|
break;
|
||||||
case SIL_CHLD:
|
case SIL_CHLD:
|
||||||
to->si_pid = from->si_pid;
|
to->si_pid = from->si_pid;
|
||||||
|
@ -4644,11 +4651,13 @@ static inline void siginfo_buildtime_checks(void)
|
||||||
|
|
||||||
/* sigfault */
|
/* sigfault */
|
||||||
CHECK_OFFSET(si_addr);
|
CHECK_OFFSET(si_addr);
|
||||||
|
CHECK_OFFSET(si_trapno);
|
||||||
CHECK_OFFSET(si_addr_lsb);
|
CHECK_OFFSET(si_addr_lsb);
|
||||||
CHECK_OFFSET(si_lower);
|
CHECK_OFFSET(si_lower);
|
||||||
CHECK_OFFSET(si_upper);
|
CHECK_OFFSET(si_upper);
|
||||||
CHECK_OFFSET(si_pkey);
|
CHECK_OFFSET(si_pkey);
|
||||||
CHECK_OFFSET(si_perf);
|
CHECK_OFFSET(si_perf_data);
|
||||||
|
CHECK_OFFSET(si_perf_type);
|
||||||
|
|
||||||
/* sigpoll */
|
/* sigpoll */
|
||||||
CHECK_OFFSET(si_band);
|
CHECK_OFFSET(si_band);
|
||||||
|
|
|
@ -43,7 +43,7 @@ static struct {
|
||||||
siginfo_t first_siginfo; /* First observed siginfo_t. */
|
siginfo_t first_siginfo; /* First observed siginfo_t. */
|
||||||
} ctx;
|
} ctx;
|
||||||
|
|
||||||
/* Unique value to check si_perf is correctly set from perf_event_attr::sig_data. */
|
/* Unique value to check si_perf_data is correctly set from perf_event_attr::sig_data. */
|
||||||
#define TEST_SIG_DATA(addr) (~(unsigned long)(addr))
|
#define TEST_SIG_DATA(addr) (~(unsigned long)(addr))
|
||||||
|
|
||||||
static struct perf_event_attr make_event_attr(bool enabled, volatile void *addr)
|
static struct perf_event_attr make_event_attr(bool enabled, volatile void *addr)
|
||||||
|
@ -164,8 +164,8 @@ TEST_F(sigtrap_threads, enable_event)
|
||||||
EXPECT_EQ(ctx.signal_count, NUM_THREADS);
|
EXPECT_EQ(ctx.signal_count, NUM_THREADS);
|
||||||
EXPECT_EQ(ctx.tids_want_signal, 0);
|
EXPECT_EQ(ctx.tids_want_signal, 0);
|
||||||
EXPECT_EQ(ctx.first_siginfo.si_addr, &ctx.iterate_on);
|
EXPECT_EQ(ctx.first_siginfo.si_addr, &ctx.iterate_on);
|
||||||
EXPECT_EQ(ctx.first_siginfo.si_errno, PERF_TYPE_BREAKPOINT);
|
EXPECT_EQ(ctx.first_siginfo.si_perf_type, PERF_TYPE_BREAKPOINT);
|
||||||
EXPECT_EQ(ctx.first_siginfo.si_perf, TEST_SIG_DATA(&ctx.iterate_on));
|
EXPECT_EQ(ctx.first_siginfo.si_perf_data, TEST_SIG_DATA(&ctx.iterate_on));
|
||||||
|
|
||||||
/* Check enabled for parent. */
|
/* Check enabled for parent. */
|
||||||
ctx.iterate_on = 0;
|
ctx.iterate_on = 0;
|
||||||
|
@ -183,8 +183,8 @@ TEST_F(sigtrap_threads, modify_and_enable_event)
|
||||||
EXPECT_EQ(ctx.signal_count, NUM_THREADS);
|
EXPECT_EQ(ctx.signal_count, NUM_THREADS);
|
||||||
EXPECT_EQ(ctx.tids_want_signal, 0);
|
EXPECT_EQ(ctx.tids_want_signal, 0);
|
||||||
EXPECT_EQ(ctx.first_siginfo.si_addr, &ctx.iterate_on);
|
EXPECT_EQ(ctx.first_siginfo.si_addr, &ctx.iterate_on);
|
||||||
EXPECT_EQ(ctx.first_siginfo.si_errno, PERF_TYPE_BREAKPOINT);
|
EXPECT_EQ(ctx.first_siginfo.si_perf_type, PERF_TYPE_BREAKPOINT);
|
||||||
EXPECT_EQ(ctx.first_siginfo.si_perf, TEST_SIG_DATA(&ctx.iterate_on));
|
EXPECT_EQ(ctx.first_siginfo.si_perf_data, TEST_SIG_DATA(&ctx.iterate_on));
|
||||||
|
|
||||||
/* Check enabled for parent. */
|
/* Check enabled for parent. */
|
||||||
ctx.iterate_on = 0;
|
ctx.iterate_on = 0;
|
||||||
|
@ -203,8 +203,8 @@ TEST_F(sigtrap_threads, signal_stress)
|
||||||
EXPECT_EQ(ctx.signal_count, NUM_THREADS * ctx.iterate_on);
|
EXPECT_EQ(ctx.signal_count, NUM_THREADS * ctx.iterate_on);
|
||||||
EXPECT_EQ(ctx.tids_want_signal, 0);
|
EXPECT_EQ(ctx.tids_want_signal, 0);
|
||||||
EXPECT_EQ(ctx.first_siginfo.si_addr, &ctx.iterate_on);
|
EXPECT_EQ(ctx.first_siginfo.si_addr, &ctx.iterate_on);
|
||||||
EXPECT_EQ(ctx.first_siginfo.si_errno, PERF_TYPE_BREAKPOINT);
|
EXPECT_EQ(ctx.first_siginfo.si_perf_type, PERF_TYPE_BREAKPOINT);
|
||||||
EXPECT_EQ(ctx.first_siginfo.si_perf, TEST_SIG_DATA(&ctx.iterate_on));
|
EXPECT_EQ(ctx.first_siginfo.si_perf_data, TEST_SIG_DATA(&ctx.iterate_on));
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST_HARNESS_MAIN
|
TEST_HARNESS_MAIN
|
||||||
|
|
Loading…
Add table
Reference in a new issue