lkml.org 
[lkml]   [2021]   [May]   [3]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Date
    Subject[PATCH 04/12] siginfo: Move si_trapno inside the union inside _si_fault
    From: "Eric W. Biederman" <ebiederm@xmission.com>

    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
    Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
    ---
    arch/sparc/kernel/signal32.c | 10 +++++-----
    arch/sparc/kernel/signal_64.c | 10 +++++-----
    arch/x86/kernel/signal_compat.c | 3 +++
    include/linux/compat.h | 5 ++---
    include/uapi/asm-generic/siginfo.h | 7 ++-----
    kernel/signal.c | 1 +
    6 files changed, 18 insertions(+), 18 deletions(-)

    diff --git a/arch/sparc/kernel/signal32.c b/arch/sparc/kernel/signal32.c
    index 778ed5c26d4a..73fd8700df3e 100644
    --- a/arch/sparc/kernel/signal32.c
    +++ b/arch/sparc/kernel/signal32.c
    @@ -772,10 +772,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);
    diff --git a/arch/sparc/kernel/signal_64.c b/arch/sparc/kernel/signal_64.c
    index c9bbf5f29078..17913daa66c6 100644
    --- a/arch/sparc/kernel/signal_64.c
    +++ b/arch/sparc/kernel/signal_64.c
    @@ -582,10 +582,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);
    diff --git a/arch/x86/kernel/signal_compat.c b/arch/x86/kernel/signal_compat.c
    index 0e5d0a7e203b..a9fcabd8a5e5 100644
    --- a/arch/x86/kernel/signal_compat.c
    +++ b/arch/x86/kernel/signal_compat.c
    @@ -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(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);

    diff --git a/include/linux/compat.h b/include/linux/compat.h
    index f0d2dd35d408..6af7bef15e94 100644
    --- a/include/linux/compat.h
    +++ b/include/linux/compat.h
    @@ -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
    diff --git a/include/uapi/asm-generic/siginfo.h b/include/uapi/asm-generic/siginfo.h
    index 03d6f6d2c1fe..e663bf117b46 100644
    --- a/include/uapi/asm-generic/siginfo.h
    +++ b/include/uapi/asm-generic/siginfo.h
    @@ -63,9 +63,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 */
    @@ -75,6 +72,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
    @@ -150,9 +149,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
    diff --git a/kernel/signal.c b/kernel/signal.c
    index c3017aa8024a..65888aec65a0 100644
    --- a/kernel/signal.c
    +++ b/kernel/signal.c
    @@ -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);
    --
    2.30.1
    \
     
     \ /
      Last update: 2021-05-03 22:41    [W:4.627 / U:0.056 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site