Skip to content

Commit 50ae813

Browse files
committed
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>
1 parent c7fff92 commit 50ae813

7 files changed

Lines changed: 21 additions & 0 deletions

File tree

arch/arm/kernel/signal.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -737,6 +737,8 @@ static_assert(NSIGBUS == 5);
737737
static_assert(NSIGTRAP == 6);
738738
static_assert(NSIGCHLD == 6);
739739
static_assert(NSIGSYS == 2);
740+
static_assert(sizeof(siginfo_t) == 128);
741+
static_assert(__alignof__(siginfo_t) == 4);
740742
static_assert(offsetof(siginfo_t, si_signo) == 0x00);
741743
static_assert(offsetof(siginfo_t, si_errno) == 0x04);
742744
static_assert(offsetof(siginfo_t, si_code) == 0x08);

arch/arm64/kernel/signal.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1011,6 +1011,8 @@ static_assert(NSIGBUS == 5);
10111011
static_assert(NSIGTRAP == 6);
10121012
static_assert(NSIGCHLD == 6);
10131013
static_assert(NSIGSYS == 2);
1014+
static_assert(sizeof(siginfo_t) == 128);
1015+
static_assert(__alignof__(siginfo_t) == 8);
10141016
static_assert(offsetof(siginfo_t, si_signo) == 0x00);
10151017
static_assert(offsetof(siginfo_t, si_errno) == 0x04);
10161018
static_assert(offsetof(siginfo_t, si_code) == 0x08);

arch/arm64/kernel/signal32.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,8 @@ static_assert(NSIGBUS == 5);
469469
static_assert(NSIGTRAP == 6);
470470
static_assert(NSIGCHLD == 6);
471471
static_assert(NSIGSYS == 2);
472+
static_assert(sizeof(compat_siginfo_t) == 128);
473+
static_assert(__alignof__(compat_siginfo_t) == 4);
472474
static_assert(offsetof(compat_siginfo_t, si_signo) == 0x00);
473475
static_assert(offsetof(compat_siginfo_t, si_errno) == 0x04);
474476
static_assert(offsetof(compat_siginfo_t, si_code) == 0x08);

arch/sparc/kernel/signal32.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -757,6 +757,8 @@ static_assert(NSIGBUS == 5);
757757
static_assert(NSIGTRAP == 6);
758758
static_assert(NSIGCHLD == 6);
759759
static_assert(NSIGSYS == 2);
760+
static_assert(sizeof(compat_siginfo_t) == 128);
761+
static_assert(__alignof__(compat_siginfo_t) == 4);
760762
static_assert(offsetof(compat_siginfo_t, si_signo) == 0x00);
761763
static_assert(offsetof(compat_siginfo_t, si_errno) == 0x04);
762764
static_assert(offsetof(compat_siginfo_t, si_code) == 0x08);

arch/sparc/kernel/signal_64.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -567,6 +567,8 @@ static_assert(NSIGBUS == 5);
567567
static_assert(NSIGTRAP == 6);
568568
static_assert(NSIGCHLD == 6);
569569
static_assert(NSIGSYS == 2);
570+
static_assert(sizeof(siginfo_t) == 128);
571+
static_assert(__alignof__(siginfo_t) == 8);
570572
static_assert(offsetof(siginfo_t, si_signo) == 0x00);
571573
static_assert(offsetof(siginfo_t, si_errno) == 0x04);
572574
static_assert(offsetof(siginfo_t, si_code) == 0x08);

arch/x86/kernel/signal_compat.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,13 @@ static inline void signal_compat_build_tests(void)
3434
BUILD_BUG_ON(NSIGSYS != 2);
3535

3636
/* This is part of the ABI and can never change in size: */
37+
BUILD_BUG_ON(sizeof(siginfo_t) != 128);
3738
BUILD_BUG_ON(sizeof(compat_siginfo_t) != 128);
39+
40+
/* This is a part of the ABI and can never change in alignment */
41+
BUILD_BUG_ON(__alignof__(siginfo_t) != 8);
42+
BUILD_BUG_ON(__alignof__(compat_siginfo_t) != 4);
43+
3844
/*
3945
* The offsets of all the (unioned) si_fields are fixed
4046
* in the ABI, of course. Make sure none of them ever

include/uapi/asm-generic/siginfo.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ typedef union sigval {
2929
#define __ARCH_SI_ATTRIBUTES
3030
#endif
3131

32+
/*
33+
* Be careful when extending this union. On 32bit siginfo_t is 32bit
34+
* aligned. Which means that a 64bit field or any other field that
35+
* would increase the alignment of siginfo_t will break the ABI.
36+
*/
3237
union __sifields {
3338
/* kill() */
3439
struct {

0 commit comments

Comments
 (0)