]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
siginfo: Move si_trapno inside the union inside _si_fault
authorEric W. Biederman <ebiederm@xmission.com>
Fri, 30 Apr 2021 22:06:01 +0000 (17:06 -0500)
committerEric W. Biederman <ebiederm@xmission.com>
Wed, 5 May 2021 17:49:06 +0000 (12:49 -0500)
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 alligned on most
architectures because the union followes 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.com
Acked-by: Marco Elver <elver@google.com>
v1: https://lkml.kernel.org/r/m1tunns7yf.fsf_-_@fess.ebiederm.org
Link: https://lkml.kernel.org/r/20210505141101.11519-5-ebiederm@xmission.com
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
arch/sparc/kernel/signal32.c
arch/sparc/kernel/signal_64.c
arch/x86/kernel/signal_compat.c
include/linux/compat.h
include/uapi/asm-generic/siginfo.h
kernel/signal.c

index 32b977f253e3276e74bf57fe127a4aa91d596eea..5573722e34adc2df3e6abdf175e4c292659785df 100644 (file)
@@ -774,10 +774,10 @@ static_assert(offsetof(compat_siginfo_t, si_int)  == 0x14);
 static_assert(offsetof(compat_siginfo_t, si_ptr)       == 0x14);
 static_assert(offsetof(compat_siginfo_t, si_addr)      == 0x0c);
 static_assert(offsetof(compat_siginfo_t, si_trapno)    == 0x10);
-static_assert(offsetof(compat_siginfo_t, si_addr_lsb)  == 0x14);
-static_assert(offsetof(compat_siginfo_t, si_lower)     == 0x18);
-static_assert(offsetof(compat_siginfo_t, si_upper)     == 0x1c);
-static_assert(offsetof(compat_siginfo_t, si_pkey)      == 0x18);
-static_assert(offsetof(compat_siginfo_t, si_perf)      == 0x14);
+static_assert(offsetof(compat_siginfo_t, si_addr_lsb)  == 0x10);
+static_assert(offsetof(compat_siginfo_t, si_lower)     == 0x14);
+static_assert(offsetof(compat_siginfo_t, si_upper)     == 0x18);
+static_assert(offsetof(compat_siginfo_t, si_pkey)      == 0x14);
+static_assert(offsetof(compat_siginfo_t, si_perf)      == 0x10);
 static_assert(offsetof(compat_siginfo_t, si_band)      == 0x0c);
 static_assert(offsetof(compat_siginfo_t, si_fd)                == 0x10);
index e9dda9db156c4305333df1a972ef6a33ea72aa58..a69a78984c367dfe73fce055d5d2106107c782d4 100644 (file)
@@ -584,10 +584,10 @@ static_assert(offsetof(siginfo_t, si_int) == 0x18);
 static_assert(offsetof(siginfo_t, si_ptr)      == 0x18);
 static_assert(offsetof(siginfo_t, si_addr)     == 0x10);
 static_assert(offsetof(siginfo_t, si_trapno)   == 0x18);
-static_assert(offsetof(siginfo_t, si_addr_lsb) == 0x20);
-static_assert(offsetof(siginfo_t, si_lower)    == 0x28);
-static_assert(offsetof(siginfo_t, si_upper)    == 0x30);
-static_assert(offsetof(siginfo_t, si_pkey)     == 0x28);
-static_assert(offsetof(siginfo_t, si_perf)     == 0x20);
+static_assert(offsetof(siginfo_t, si_addr_lsb) == 0x18);
+static_assert(offsetof(siginfo_t, si_lower)    == 0x20);
+static_assert(offsetof(siginfo_t, si_upper)    == 0x28);
+static_assert(offsetof(siginfo_t, si_pkey)     == 0x20);
+static_assert(offsetof(siginfo_t, si_perf)     == 0x18);
 static_assert(offsetof(siginfo_t, si_band)     == 0x10);
 static_assert(offsetof(siginfo_t, si_fd)       == 0x14);
index e735bc1293312a561d349124d2fe7c39aa8612a6..c9601f092a1e5840444575867849bc3cb7884b58 100644 (file)
@@ -133,6 +133,9 @@ static inline void signal_compat_build_tests(void)
        BUILD_BUG_ON(offsetof(siginfo_t, si_addr) != 0x10);
        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(compat_siginfo_t, si_addr_lsb) != 0x10);
 
index f0d2dd35d408bd2406cb4080d9671535ec1b2299..6af7bef15e94984b2529a505476961e16ca80ada 100644 (file)
@@ -214,12 +214,11 @@ typedef struct compat_siginfo {
                /* SIGILL, SIGFPE, SIGSEGV, SIGBUS, SIGTRAP, SIGEMT */
                struct {
                        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) ? \
                                     sizeof(short) : __alignof__(compat_uptr_t))
                        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_AO
index 91c80d0c10c56d68c6d44f33f797394d3cf0de1b..3503282021aac9c32255e0ea692f8acaa8f9c9c4 100644 (file)
@@ -68,9 +68,6 @@ union __sifields {
        /* SIGILL, SIGFPE, SIGSEGV, SIGBUS, SIGTRAP, SIGEMT */
        struct {
                void __user *_addr; /* faulting insn/memory ref. */
-#ifdef __ARCH_SI_TRAPNO
-               int _trapno;    /* TRAP # which caused the signal */
-#endif
 #ifdef __ia64__
                int _imm;               /* immediate value for "break" */
                unsigned int _flags;    /* see ia64 si_flags */
@@ -80,6 +77,8 @@ union __sifields {
 #define __ADDR_BND_PKEY_PAD  (__alignof__(void *) < sizeof(short) ? \
                              sizeof(short) : __alignof__(void *))
                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_AO
@@ -155,9 +154,7 @@ typedef struct siginfo {
 #define si_int         _sifields._rt._sigval.sival_int
 #define si_ptr         _sifields._rt._sigval.sival_ptr
 #define si_addr                _sifields._sigfault._addr
-#ifdef __ARCH_SI_TRAPNO
 #define si_trapno      _sifields._sigfault._trapno
-#endif
 #define si_addr_lsb    _sifields._sigfault._addr_lsb
 #define si_lower       _sifields._sigfault._addr_bnd._lower
 #define si_upper       _sifields._sigfault._addr_bnd._upper
index c3017aa8024a095dfa1fa61bce2f2b846a9badb0..65888aec65a0fcfb842afcf459ec391cbe0ecf44 100644 (file)
@@ -4607,6 +4607,7 @@ static inline void siginfo_buildtime_checks(void)
 
        /* sigfault */
        CHECK_OFFSET(si_addr);
+       CHECK_OFFSET(si_trapno);
        CHECK_OFFSET(si_addr_lsb);
        CHECK_OFFSET(si_lower);
        CHECK_OFFSET(si_upper);