Commit add0b32e authored by Eric W. Biederman's avatar Eric W. Biederman

siginfo: Move si_trapno inside the union inside _si_fault

It turns out that linux uses si_trapno very sparingly, and as such it
can be considered extra information for a very narrow selection of
signals, rather than information that is present with every fault
reported in siginfo.

As such move si_trapno inside the union inside of _si_fault.  This
results in no change in placement, and makes it eaiser
to extend _si_fault in the future as this reduces the number of
special cases.  In particular with si_trapno included in the union it
is no longer a concern that the union must be pointer aligned on most
architectures because the union follows immediately after si_addr
which is a pointer.

This change results in a difference in siginfo field placement on
sparc and alpha for the fields si_addr_lsb, si_lower, si_upper,
si_pkey, and si_perf.  These architectures do not implement the
signals that would use si_addr_lsb, si_lower, si_upper, si_pkey, and
si_perf.  Further these architecture have not yet implemented the
userspace that would use si_perf.

The point of this change is in fact to correct these placement issues
before sparc or alpha grow userspace that cares.  This change was
discussed[1] and the agreement is that this change is currently safe.

[1]: https://lkml.kernel.org/r/CAK8P3a0+uKYwL1NhY6Hvtieghba2hKYGD6hcKx5n8=4Gtt+pHA@mail.gmail.comAcked-by: default avatarMarco Elver <elver@google.com>
v1: https://lkml.kernel.org/r/m1tunns7yf.fsf_-_@fess.ebiederm.org
v2: https://lkml.kernel.org/r/20210505141101.11519-5-ebiederm@xmission.com
Link: https://lkml.kernel.org/r/20210517195748.8880-1-ebiederm@xmission.comSigned-off-by: default avatar"Eric W. Biederman" <ebiederm@xmission.com>
parent 42dec9a9
...@@ -127,6 +127,9 @@ static inline void signal_compat_build_tests(void) ...@@ -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);
......
...@@ -214,12 +214,11 @@ typedef struct compat_siginfo { ...@@ -214,12 +214,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
......
...@@ -63,9 +63,6 @@ union __sifields { ...@@ -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 { ...@@ -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
...@@ -150,9 +149,7 @@ typedef struct siginfo { ...@@ -150,9 +149,7 @@ 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
......
...@@ -4607,6 +4607,7 @@ static inline void siginfo_buildtime_checks(void) ...@@ -4607,6 +4607,7 @@ 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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment