Skip to content

Commit f6e2a56

Browse files
Brian GerstIngo Molnar
authored andcommitted
x86/signal: Move siginfo field tests
Move the tests to the appropriate signal_$(BITS).c file. Convert them to use static_assert(), removing the need for a dummy function. Signed-off-by: Brian Gerst <[email protected]> Signed-off-by: Ingo Molnar <[email protected]> Link: https://lore.kernel.org/r/[email protected] Cc: Al Viro <[email protected]>
1 parent 41c03ba commit f6e2a56

File tree

3 files changed

+241
-176
lines changed

3 files changed

+241
-176
lines changed

arch/x86/kernel/signal_32.c

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,14 @@ static inline void reload_segments(struct sigcontext_32 *sc)
5454
}
5555

5656
#define sigset32_t compat_sigset_t
57+
#define siginfo32_t compat_siginfo_t
5758
#define restore_altstack32 compat_restore_altstack
5859
#define unsafe_save_altstack32 unsafe_compat_save_altstack
5960

6061
#else
6162

6263
#define sigset32_t sigset_t
64+
#define siginfo32_t siginfo_t
6365
#define __NR_ia32_sigreturn __NR_sigreturn
6466
#define __NR_ia32_rt_sigreturn __NR_rt_sigreturn
6567
#define restore_altstack32 restore_altstack
@@ -377,3 +379,128 @@ int ia32_setup_rt_frame(struct ksignal *ksig, struct pt_regs *regs)
377379
user_access_end();
378380
return -EFAULT;
379381
}
382+
383+
/*
384+
* The siginfo_t structure and handing code is very easy
385+
* to break in several ways. It must always be updated when new
386+
* updates are made to the main siginfo_t, and
387+
* copy_siginfo_to_user32() must be updated when the
388+
* (arch-independent) copy_siginfo_to_user() is updated.
389+
*
390+
* It is also easy to put a new member in the siginfo_t
391+
* which has implicit alignment which can move internal structure
392+
* alignment around breaking the ABI. This can happen if you,
393+
* for instance, put a plain 64-bit value in there.
394+
*/
395+
396+
/*
397+
* If adding a new si_code, there is probably new data in
398+
* the siginfo. Make sure folks bumping the si_code
399+
* limits also have to look at this code. Make sure any
400+
* new fields are handled in copy_siginfo_to_user32()!
401+
*/
402+
static_assert(NSIGILL == 11);
403+
static_assert(NSIGFPE == 15);
404+
static_assert(NSIGSEGV == 9);
405+
static_assert(NSIGBUS == 5);
406+
static_assert(NSIGTRAP == 6);
407+
static_assert(NSIGCHLD == 6);
408+
static_assert(NSIGSYS == 2);
409+
410+
/* This is part of the ABI and can never change in size: */
411+
static_assert(sizeof(siginfo32_t) == 128);
412+
413+
/* This is a part of the ABI and can never change in alignment */
414+
static_assert(__alignof__(siginfo32_t) == 4);
415+
416+
/*
417+
* The offsets of all the (unioned) si_fields are fixed
418+
* in the ABI, of course. Make sure none of them ever
419+
* move and are always at the beginning:
420+
*/
421+
static_assert(offsetof(siginfo32_t, _sifields) == 3 * sizeof(int));
422+
423+
static_assert(offsetof(siginfo32_t, si_signo) == 0);
424+
static_assert(offsetof(siginfo32_t, si_errno) == 4);
425+
static_assert(offsetof(siginfo32_t, si_code) == 8);
426+
427+
/*
428+
* Ensure that the size of each si_field never changes.
429+
* If it does, it is a sign that the
430+
* copy_siginfo_to_user32() code below needs to updated
431+
* along with the size in the CHECK_SI_SIZE().
432+
*
433+
* We repeat this check for both the generic and compat
434+
* siginfos.
435+
*
436+
* Note: it is OK for these to grow as long as the whole
437+
* structure stays within the padding size (checked
438+
* above).
439+
*/
440+
441+
#define CHECK_SI_OFFSET(name) \
442+
static_assert(offsetof(siginfo32_t, _sifields) == \
443+
offsetof(siginfo32_t, _sifields.name))
444+
445+
#define CHECK_SI_SIZE(name, size) \
446+
static_assert(sizeof_field(siginfo32_t, _sifields.name) == size)
447+
448+
CHECK_SI_OFFSET(_kill);
449+
CHECK_SI_SIZE (_kill, 2*sizeof(int));
450+
static_assert(offsetof(siginfo32_t, si_pid) == 0xC);
451+
static_assert(offsetof(siginfo32_t, si_uid) == 0x10);
452+
453+
CHECK_SI_OFFSET(_timer);
454+
#ifdef CONFIG_COMPAT
455+
/* compat_siginfo_t doesn't have si_sys_private */
456+
CHECK_SI_SIZE (_timer, 3*sizeof(int));
457+
#else
458+
CHECK_SI_SIZE (_timer, 4*sizeof(int));
459+
#endif
460+
static_assert(offsetof(siginfo32_t, si_tid) == 0x0C);
461+
static_assert(offsetof(siginfo32_t, si_overrun) == 0x10);
462+
static_assert(offsetof(siginfo32_t, si_value) == 0x14);
463+
464+
CHECK_SI_OFFSET(_rt);
465+
CHECK_SI_SIZE (_rt, 3*sizeof(int));
466+
static_assert(offsetof(siginfo32_t, si_pid) == 0x0C);
467+
static_assert(offsetof(siginfo32_t, si_uid) == 0x10);
468+
static_assert(offsetof(siginfo32_t, si_value) == 0x14);
469+
470+
CHECK_SI_OFFSET(_sigchld);
471+
CHECK_SI_SIZE (_sigchld, 5*sizeof(int));
472+
static_assert(offsetof(siginfo32_t, si_pid) == 0x0C);
473+
static_assert(offsetof(siginfo32_t, si_uid) == 0x10);
474+
static_assert(offsetof(siginfo32_t, si_status) == 0x14);
475+
static_assert(offsetof(siginfo32_t, si_utime) == 0x18);
476+
static_assert(offsetof(siginfo32_t, si_stime) == 0x1C);
477+
478+
CHECK_SI_OFFSET(_sigfault);
479+
CHECK_SI_SIZE (_sigfault, 4*sizeof(int));
480+
static_assert(offsetof(siginfo32_t, si_addr) == 0x0C);
481+
482+
static_assert(offsetof(siginfo32_t, si_trapno) == 0x10);
483+
484+
static_assert(offsetof(siginfo32_t, si_addr_lsb) == 0x10);
485+
486+
static_assert(offsetof(siginfo32_t, si_lower) == 0x14);
487+
static_assert(offsetof(siginfo32_t, si_upper) == 0x18);
488+
489+
static_assert(offsetof(siginfo32_t, si_pkey) == 0x14);
490+
491+
static_assert(offsetof(siginfo32_t, si_perf_data) == 0x10);
492+
static_assert(offsetof(siginfo32_t, si_perf_type) == 0x14);
493+
static_assert(offsetof(siginfo32_t, si_perf_flags) == 0x18);
494+
495+
CHECK_SI_OFFSET(_sigpoll);
496+
CHECK_SI_SIZE (_sigpoll, 2*sizeof(int));
497+
static_assert(offsetof(siginfo32_t, si_band) == 0x0C);
498+
static_assert(offsetof(siginfo32_t, si_fd) == 0x10);
499+
500+
CHECK_SI_OFFSET(_sigsys);
501+
CHECK_SI_SIZE (_sigsys, 3*sizeof(int));
502+
static_assert(offsetof(siginfo32_t, si_call_addr) == 0x0C);
503+
static_assert(offsetof(siginfo32_t, si_syscall) == 0x10);
504+
static_assert(offsetof(siginfo32_t, si_arch) == 0x14);
505+
506+
/* any new si_fields should be added here */

arch/x86/kernel/signal_64.c

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,3 +381,117 @@ COMPAT_SYSCALL_DEFINE0(x32_rt_sigreturn)
381381
return 0;
382382
}
383383
#endif /* CONFIG_X86_X32_ABI */
384+
385+
/*
386+
* If adding a new si_code, there is probably new data in
387+
* the siginfo. Make sure folks bumping the si_code
388+
* limits also have to look at this code. Make sure any
389+
* new fields are handled in copy_siginfo_to_user32()!
390+
*/
391+
static_assert(NSIGILL == 11);
392+
static_assert(NSIGFPE == 15);
393+
static_assert(NSIGSEGV == 9);
394+
static_assert(NSIGBUS == 5);
395+
static_assert(NSIGTRAP == 6);
396+
static_assert(NSIGCHLD == 6);
397+
static_assert(NSIGSYS == 2);
398+
399+
/* This is part of the ABI and can never change in size: */
400+
static_assert(sizeof(siginfo_t) == 128);
401+
402+
/* This is a part of the ABI and can never change in alignment */
403+
static_assert(__alignof__(siginfo_t) == 8);
404+
405+
/*
406+
* The offsets of all the (unioned) si_fields are fixed
407+
* in the ABI, of course. Make sure none of them ever
408+
* move and are always at the beginning:
409+
*/
410+
static_assert(offsetof(siginfo_t, si_signo) == 0);
411+
static_assert(offsetof(siginfo_t, si_errno) == 4);
412+
static_assert(offsetof(siginfo_t, si_code) == 8);
413+
414+
/*
415+
* Ensure that the size of each si_field never changes.
416+
* If it does, it is a sign that the
417+
* copy_siginfo_to_user32() code below needs to updated
418+
* along with the size in the CHECK_SI_SIZE().
419+
*
420+
* We repeat this check for both the generic and compat
421+
* siginfos.
422+
*
423+
* Note: it is OK for these to grow as long as the whole
424+
* structure stays within the padding size (checked
425+
* above).
426+
*/
427+
428+
#define CHECK_SI_OFFSET(name) \
429+
static_assert(offsetof(siginfo_t, _sifields) == \
430+
offsetof(siginfo_t, _sifields.name))
431+
#define CHECK_SI_SIZE(name, size) \
432+
static_assert(sizeof_field(siginfo_t, _sifields.name) == size)
433+
434+
CHECK_SI_OFFSET(_kill);
435+
CHECK_SI_SIZE (_kill, 2*sizeof(int));
436+
static_assert(offsetof(siginfo_t, si_pid) == 0x10);
437+
static_assert(offsetof(siginfo_t, si_uid) == 0x14);
438+
439+
CHECK_SI_OFFSET(_timer);
440+
CHECK_SI_SIZE (_timer, 6*sizeof(int));
441+
static_assert(offsetof(siginfo_t, si_tid) == 0x10);
442+
static_assert(offsetof(siginfo_t, si_overrun) == 0x14);
443+
static_assert(offsetof(siginfo_t, si_value) == 0x18);
444+
445+
CHECK_SI_OFFSET(_rt);
446+
CHECK_SI_SIZE (_rt, 4*sizeof(int));
447+
static_assert(offsetof(siginfo_t, si_pid) == 0x10);
448+
static_assert(offsetof(siginfo_t, si_uid) == 0x14);
449+
static_assert(offsetof(siginfo_t, si_value) == 0x18);
450+
451+
CHECK_SI_OFFSET(_sigchld);
452+
CHECK_SI_SIZE (_sigchld, 8*sizeof(int));
453+
static_assert(offsetof(siginfo_t, si_pid) == 0x10);
454+
static_assert(offsetof(siginfo_t, si_uid) == 0x14);
455+
static_assert(offsetof(siginfo_t, si_status) == 0x18);
456+
static_assert(offsetof(siginfo_t, si_utime) == 0x20);
457+
static_assert(offsetof(siginfo_t, si_stime) == 0x28);
458+
459+
#ifdef CONFIG_X86_X32_ABI
460+
/* no _sigchld_x32 in the generic siginfo_t */
461+
static_assert(sizeof_field(compat_siginfo_t, _sifields._sigchld_x32) ==
462+
7*sizeof(int));
463+
static_assert(offsetof(compat_siginfo_t, _sifields) ==
464+
offsetof(compat_siginfo_t, _sifields._sigchld_x32));
465+
static_assert(offsetof(compat_siginfo_t, _sifields._sigchld_x32._utime) == 0x18);
466+
static_assert(offsetof(compat_siginfo_t, _sifields._sigchld_x32._stime) == 0x20);
467+
#endif
468+
469+
CHECK_SI_OFFSET(_sigfault);
470+
CHECK_SI_SIZE (_sigfault, 8*sizeof(int));
471+
static_assert(offsetof(siginfo_t, si_addr) == 0x10);
472+
473+
static_assert(offsetof(siginfo_t, si_trapno) == 0x18);
474+
475+
static_assert(offsetof(siginfo_t, si_addr_lsb) == 0x18);
476+
477+
static_assert(offsetof(siginfo_t, si_lower) == 0x20);
478+
static_assert(offsetof(siginfo_t, si_upper) == 0x28);
479+
480+
static_assert(offsetof(siginfo_t, si_pkey) == 0x20);
481+
482+
static_assert(offsetof(siginfo_t, si_perf_data) == 0x18);
483+
static_assert(offsetof(siginfo_t, si_perf_type) == 0x20);
484+
static_assert(offsetof(siginfo_t, si_perf_flags) == 0x24);
485+
486+
CHECK_SI_OFFSET(_sigpoll);
487+
CHECK_SI_SIZE (_sigpoll, 4*sizeof(int));
488+
static_assert(offsetof(siginfo_t, si_band) == 0x10);
489+
static_assert(offsetof(siginfo_t, si_fd) == 0x18);
490+
491+
CHECK_SI_OFFSET(_sigsys);
492+
CHECK_SI_SIZE (_sigsys, 4*sizeof(int));
493+
static_assert(offsetof(siginfo_t, si_call_addr) == 0x10);
494+
static_assert(offsetof(siginfo_t, si_syscall) == 0x18);
495+
static_assert(offsetof(siginfo_t, si_arch) == 0x1C);
496+
497+
/* any new si_fields should be added here */

0 commit comments

Comments
 (0)