Skip to content

Commit 8a68bd3

Browse files
committed
Merge tag 'x86-core-2023-02-20' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 core updates from Ingo Molnar: - Clean up the signal frame layout tests - Suppress KMSAN false positive reports in arch_within_stack_frames() * tag 'x86-core-2023-02-20' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86: Suppress KMSAN reports in arch_within_stack_frames() x86/signal/compat: Move sigaction_compat_abi() to signal_64.c x86/signal: Move siginfo field tests
2 parents 572640f + ce3ba2a commit 8a68bd3

File tree

5 files changed

+259
-192
lines changed

5 files changed

+259
-192
lines changed

arch/x86/include/asm/thread_info.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,12 @@ struct thread_info {
163163
* GOOD_FRAME if within a frame
164164
* BAD_STACK if placed across a frame boundary (or outside stack)
165165
* NOT_STACK unable to determine (no frame pointers, etc)
166+
*
167+
* This function reads pointers from the stack and dereferences them. The
168+
* pointers may not have their KMSAN shadow set up properly, which may result
169+
* in false positive reports. Disable instrumentation to avoid those.
166170
*/
171+
__no_kmsan_checks
167172
static inline int arch_within_stack_frames(const void * const stack,
168173
const void * const stackend,
169174
const void *obj, unsigned long len)

arch/x86/kernel/Makefile

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,6 @@ obj-y += head$(BITS).o
4545
obj-y += ebda.o
4646
obj-y += platform-quirks.o
4747
obj-y += process_$(BITS).o signal.o signal_$(BITS).o
48-
obj-$(CONFIG_COMPAT) += signal_compat.o
4948
obj-y += traps.o idt.o irq.o irq_$(BITS).o dumpstack_$(BITS).o
5049
obj-y += time.o ioport.o dumpstack.o nmi.o
5150
obj-$(CONFIG_MODIFY_LDT_SYSCALL) += ldt.o

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: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,3 +381,130 @@ COMPAT_SYSCALL_DEFINE0(x32_rt_sigreturn)
381381
return 0;
382382
}
383383
#endif /* CONFIG_X86_X32_ABI */
384+
385+
#ifdef CONFIG_COMPAT
386+
void sigaction_compat_abi(struct k_sigaction *act, struct k_sigaction *oact)
387+
{
388+
if (!act)
389+
return;
390+
391+
if (in_ia32_syscall())
392+
act->sa.sa_flags |= SA_IA32_ABI;
393+
if (in_x32_syscall())
394+
act->sa.sa_flags |= SA_X32_ABI;
395+
}
396+
#endif /* CONFIG_COMPAT */
397+
398+
/*
399+
* If adding a new si_code, there is probably new data in
400+
* the siginfo. Make sure folks bumping the si_code
401+
* limits also have to look at this code. Make sure any
402+
* new fields are handled in copy_siginfo_to_user32()!
403+
*/
404+
static_assert(NSIGILL == 11);
405+
static_assert(NSIGFPE == 15);
406+
static_assert(NSIGSEGV == 9);
407+
static_assert(NSIGBUS == 5);
408+
static_assert(NSIGTRAP == 6);
409+
static_assert(NSIGCHLD == 6);
410+
static_assert(NSIGSYS == 2);
411+
412+
/* This is part of the ABI and can never change in size: */
413+
static_assert(sizeof(siginfo_t) == 128);
414+
415+
/* This is a part of the ABI and can never change in alignment */
416+
static_assert(__alignof__(siginfo_t) == 8);
417+
418+
/*
419+
* The offsets of all the (unioned) si_fields are fixed
420+
* in the ABI, of course. Make sure none of them ever
421+
* move and are always at the beginning:
422+
*/
423+
static_assert(offsetof(siginfo_t, si_signo) == 0);
424+
static_assert(offsetof(siginfo_t, si_errno) == 4);
425+
static_assert(offsetof(siginfo_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(siginfo_t, _sifields) == \
443+
offsetof(siginfo_t, _sifields.name))
444+
#define CHECK_SI_SIZE(name, size) \
445+
static_assert(sizeof_field(siginfo_t, _sifields.name) == size)
446+
447+
CHECK_SI_OFFSET(_kill);
448+
CHECK_SI_SIZE (_kill, 2*sizeof(int));
449+
static_assert(offsetof(siginfo_t, si_pid) == 0x10);
450+
static_assert(offsetof(siginfo_t, si_uid) == 0x14);
451+
452+
CHECK_SI_OFFSET(_timer);
453+
CHECK_SI_SIZE (_timer, 6*sizeof(int));
454+
static_assert(offsetof(siginfo_t, si_tid) == 0x10);
455+
static_assert(offsetof(siginfo_t, si_overrun) == 0x14);
456+
static_assert(offsetof(siginfo_t, si_value) == 0x18);
457+
458+
CHECK_SI_OFFSET(_rt);
459+
CHECK_SI_SIZE (_rt, 4*sizeof(int));
460+
static_assert(offsetof(siginfo_t, si_pid) == 0x10);
461+
static_assert(offsetof(siginfo_t, si_uid) == 0x14);
462+
static_assert(offsetof(siginfo_t, si_value) == 0x18);
463+
464+
CHECK_SI_OFFSET(_sigchld);
465+
CHECK_SI_SIZE (_sigchld, 8*sizeof(int));
466+
static_assert(offsetof(siginfo_t, si_pid) == 0x10);
467+
static_assert(offsetof(siginfo_t, si_uid) == 0x14);
468+
static_assert(offsetof(siginfo_t, si_status) == 0x18);
469+
static_assert(offsetof(siginfo_t, si_utime) == 0x20);
470+
static_assert(offsetof(siginfo_t, si_stime) == 0x28);
471+
472+
#ifdef CONFIG_X86_X32_ABI
473+
/* no _sigchld_x32 in the generic siginfo_t */
474+
static_assert(sizeof_field(compat_siginfo_t, _sifields._sigchld_x32) ==
475+
7*sizeof(int));
476+
static_assert(offsetof(compat_siginfo_t, _sifields) ==
477+
offsetof(compat_siginfo_t, _sifields._sigchld_x32));
478+
static_assert(offsetof(compat_siginfo_t, _sifields._sigchld_x32._utime) == 0x18);
479+
static_assert(offsetof(compat_siginfo_t, _sifields._sigchld_x32._stime) == 0x20);
480+
#endif
481+
482+
CHECK_SI_OFFSET(_sigfault);
483+
CHECK_SI_SIZE (_sigfault, 8*sizeof(int));
484+
static_assert(offsetof(siginfo_t, si_addr) == 0x10);
485+
486+
static_assert(offsetof(siginfo_t, si_trapno) == 0x18);
487+
488+
static_assert(offsetof(siginfo_t, si_addr_lsb) == 0x18);
489+
490+
static_assert(offsetof(siginfo_t, si_lower) == 0x20);
491+
static_assert(offsetof(siginfo_t, si_upper) == 0x28);
492+
493+
static_assert(offsetof(siginfo_t, si_pkey) == 0x20);
494+
495+
static_assert(offsetof(siginfo_t, si_perf_data) == 0x18);
496+
static_assert(offsetof(siginfo_t, si_perf_type) == 0x20);
497+
static_assert(offsetof(siginfo_t, si_perf_flags) == 0x24);
498+
499+
CHECK_SI_OFFSET(_sigpoll);
500+
CHECK_SI_SIZE (_sigpoll, 4*sizeof(int));
501+
static_assert(offsetof(siginfo_t, si_band) == 0x10);
502+
static_assert(offsetof(siginfo_t, si_fd) == 0x18);
503+
504+
CHECK_SI_OFFSET(_sigsys);
505+
CHECK_SI_SIZE (_sigsys, 4*sizeof(int));
506+
static_assert(offsetof(siginfo_t, si_call_addr) == 0x10);
507+
static_assert(offsetof(siginfo_t, si_syscall) == 0x18);
508+
static_assert(offsetof(siginfo_t, si_arch) == 0x1C);
509+
510+
/* any new si_fields should be added here */

0 commit comments

Comments
 (0)