signal: Verify the alignment and size of siginfo_t

Update the static assertions about siginfo_t to also describe
it's alignment and size.

While investigating if it was possible to add a 64bit field into
siginfo_t[1] it became apparent that the alignment of siginfo_t
is as much a part of the ABI as the size of the structure.

If the alignment changes siginfo_t when embedded in another structure
can move to a different offset.  Which is not acceptable from an ABI
structure.

So document that fact and add static assertions to notify developers
if they change change the alignment by accident.

[1] https://lkml.kernel.org/r/YJEZdhe6JGFNYlum@elver.google.com
Acked-by: Marco Elver <elver@google.com>
v1: https://lkml.kernel.org/r/20210505141101.11519-4-ebiederm@xmission.co
Link: https://lkml.kernel.org/r/875yxaxmyl.fsf_-_@disp2133
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
This commit is contained in:
Eric W. Biederman 2021-05-04 11:25:22 -05:00
parent c7fff9288d
commit 50ae81305c
7 changed files with 21 additions and 0 deletions

View File

@ -737,6 +737,8 @@ static_assert(NSIGBUS == 5);
static_assert(NSIGTRAP == 6); static_assert(NSIGTRAP == 6);
static_assert(NSIGCHLD == 6); static_assert(NSIGCHLD == 6);
static_assert(NSIGSYS == 2); static_assert(NSIGSYS == 2);
static_assert(sizeof(siginfo_t) == 128);
static_assert(__alignof__(siginfo_t) == 4);
static_assert(offsetof(siginfo_t, si_signo) == 0x00); static_assert(offsetof(siginfo_t, si_signo) == 0x00);
static_assert(offsetof(siginfo_t, si_errno) == 0x04); static_assert(offsetof(siginfo_t, si_errno) == 0x04);
static_assert(offsetof(siginfo_t, si_code) == 0x08); static_assert(offsetof(siginfo_t, si_code) == 0x08);

View File

@ -1011,6 +1011,8 @@ static_assert(NSIGBUS == 5);
static_assert(NSIGTRAP == 6); static_assert(NSIGTRAP == 6);
static_assert(NSIGCHLD == 6); static_assert(NSIGCHLD == 6);
static_assert(NSIGSYS == 2); static_assert(NSIGSYS == 2);
static_assert(sizeof(siginfo_t) == 128);
static_assert(__alignof__(siginfo_t) == 8);
static_assert(offsetof(siginfo_t, si_signo) == 0x00); static_assert(offsetof(siginfo_t, si_signo) == 0x00);
static_assert(offsetof(siginfo_t, si_errno) == 0x04); static_assert(offsetof(siginfo_t, si_errno) == 0x04);
static_assert(offsetof(siginfo_t, si_code) == 0x08); static_assert(offsetof(siginfo_t, si_code) == 0x08);

View File

@ -469,6 +469,8 @@ static_assert(NSIGBUS == 5);
static_assert(NSIGTRAP == 6); static_assert(NSIGTRAP == 6);
static_assert(NSIGCHLD == 6); static_assert(NSIGCHLD == 6);
static_assert(NSIGSYS == 2); static_assert(NSIGSYS == 2);
static_assert(sizeof(compat_siginfo_t) == 128);
static_assert(__alignof__(compat_siginfo_t) == 4);
static_assert(offsetof(compat_siginfo_t, si_signo) == 0x00); static_assert(offsetof(compat_siginfo_t, si_signo) == 0x00);
static_assert(offsetof(compat_siginfo_t, si_errno) == 0x04); static_assert(offsetof(compat_siginfo_t, si_errno) == 0x04);
static_assert(offsetof(compat_siginfo_t, si_code) == 0x08); static_assert(offsetof(compat_siginfo_t, si_code) == 0x08);

View File

@ -757,6 +757,8 @@ static_assert(NSIGBUS == 5);
static_assert(NSIGTRAP == 6); static_assert(NSIGTRAP == 6);
static_assert(NSIGCHLD == 6); static_assert(NSIGCHLD == 6);
static_assert(NSIGSYS == 2); static_assert(NSIGSYS == 2);
static_assert(sizeof(compat_siginfo_t) == 128);
static_assert(__alignof__(compat_siginfo_t) == 4);
static_assert(offsetof(compat_siginfo_t, si_signo) == 0x00); static_assert(offsetof(compat_siginfo_t, si_signo) == 0x00);
static_assert(offsetof(compat_siginfo_t, si_errno) == 0x04); static_assert(offsetof(compat_siginfo_t, si_errno) == 0x04);
static_assert(offsetof(compat_siginfo_t, si_code) == 0x08); static_assert(offsetof(compat_siginfo_t, si_code) == 0x08);

View File

@ -567,6 +567,8 @@ static_assert(NSIGBUS == 5);
static_assert(NSIGTRAP == 6); static_assert(NSIGTRAP == 6);
static_assert(NSIGCHLD == 6); static_assert(NSIGCHLD == 6);
static_assert(NSIGSYS == 2); static_assert(NSIGSYS == 2);
static_assert(sizeof(siginfo_t) == 128);
static_assert(__alignof__(siginfo_t) == 8);
static_assert(offsetof(siginfo_t, si_signo) == 0x00); static_assert(offsetof(siginfo_t, si_signo) == 0x00);
static_assert(offsetof(siginfo_t, si_errno) == 0x04); static_assert(offsetof(siginfo_t, si_errno) == 0x04);
static_assert(offsetof(siginfo_t, si_code) == 0x08); static_assert(offsetof(siginfo_t, si_code) == 0x08);

View File

@ -34,7 +34,13 @@ static inline void signal_compat_build_tests(void)
BUILD_BUG_ON(NSIGSYS != 2); BUILD_BUG_ON(NSIGSYS != 2);
/* This is part of the ABI and can never change in size: */ /* This is part of the ABI and can never change in size: */
BUILD_BUG_ON(sizeof(siginfo_t) != 128);
BUILD_BUG_ON(sizeof(compat_siginfo_t) != 128); BUILD_BUG_ON(sizeof(compat_siginfo_t) != 128);
/* This is a part of the ABI and can never change in alignment */
BUILD_BUG_ON(__alignof__(siginfo_t) != 8);
BUILD_BUG_ON(__alignof__(compat_siginfo_t) != 4);
/* /*
* The offsets of all the (unioned) si_fields are fixed * The offsets of all the (unioned) si_fields are fixed
* in the ABI, of course. Make sure none of them ever * in the ABI, of course. Make sure none of them ever

View File

@ -29,6 +29,11 @@ typedef union sigval {
#define __ARCH_SI_ATTRIBUTES #define __ARCH_SI_ATTRIBUTES
#endif #endif
/*
* Be careful when extending this union. On 32bit siginfo_t is 32bit
* aligned. Which means that a 64bit field or any other field that
* would increase the alignment of siginfo_t will break the ABI.
*/
union __sifields { union __sifields {
/* kill() */ /* kill() */
struct { struct {