Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'for-v5.13-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace

Pull siginfo fix from Eric Biederman:
"During the merge window an issue with si_perf and the siginfo ABI came
up. The alpha and sparc siginfo structure layout had changed with the
addition of SIGTRAP TRAP_PERF and the new field si_perf.

The reason only alpha and sparc were affected is that they are the
only architectures that use si_trapno.

Looking deeper it was discovered that si_trapno is used for only a few
select signals on alpha and sparc, and that none of the other
_sigfault fields past si_addr are used at all. Which means technically
no regression on alpha and sparc.

While the alignment concerns might be dismissed the abuse of si_errno
by SIGTRAP TRAP_PERF does have the potential to cause regressions in
existing userspace.

While we still have time before userspace starts using and depending
on the new definition siginfo for SIGTRAP TRAP_PERF this set of
changes cleans up siginfo_t.

- The si_trapno field is demoted from magic alpha and sparc status
and made an ordinary union member of the _sigfault member of
siginfo_t. Without moving it of course.

- si_perf is replaced with si_perf_data and si_perf_type ending the
abuse of si_errno.

- Unnecessary additions to signalfd_siginfo are removed"

* 'for-v5.13-rc3' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace:
signalfd: Remove SIL_PERF_EVENT fields from signalfd_siginfo
signal: Deliver all of the siginfo perf data in _perf
signal: Factor force_sig_perf out of perf_sigtrap
signal: Implement SIL_FAULT_TRAPNO
siginfo: Move si_trapno inside the union inside _si_fault

+79 -73
+2 -1
arch/m68k/kernel/signal.c
··· 623 623 BUILD_BUG_ON(offsetof(siginfo_t, si_pkey) != 0x12); 624 624 625 625 /* _sigfault._perf */ 626 - BUILD_BUG_ON(offsetof(siginfo_t, si_perf) != 0x10); 626 + BUILD_BUG_ON(offsetof(siginfo_t, si_perf_data) != 0x10); 627 + BUILD_BUG_ON(offsetof(siginfo_t, si_perf_type) != 0x14); 627 628 628 629 /* _sigpoll */ 629 630 BUILD_BUG_ON(offsetof(siginfo_t, si_band) != 0x0c);
+7 -2
arch/x86/kernel/signal_compat.c
··· 127 127 BUILD_BUG_ON(offsetof(siginfo_t, si_addr) != 0x10); 128 128 BUILD_BUG_ON(offsetof(compat_siginfo_t, si_addr) != 0x0C); 129 129 130 + BUILD_BUG_ON(offsetof(siginfo_t, si_trapno) != 0x18); 131 + BUILD_BUG_ON(offsetof(compat_siginfo_t, si_trapno) != 0x10); 132 + 130 133 BUILD_BUG_ON(offsetof(siginfo_t, si_addr_lsb) != 0x18); 131 134 BUILD_BUG_ON(offsetof(compat_siginfo_t, si_addr_lsb) != 0x10); 132 135 ··· 141 138 BUILD_BUG_ON(offsetof(siginfo_t, si_pkey) != 0x20); 142 139 BUILD_BUG_ON(offsetof(compat_siginfo_t, si_pkey) != 0x14); 143 140 144 - BUILD_BUG_ON(offsetof(siginfo_t, si_perf) != 0x18); 145 - BUILD_BUG_ON(offsetof(compat_siginfo_t, si_perf) != 0x10); 141 + BUILD_BUG_ON(offsetof(siginfo_t, si_perf_data) != 0x18); 142 + BUILD_BUG_ON(offsetof(siginfo_t, si_perf_type) != 0x20); 143 + BUILD_BUG_ON(offsetof(compat_siginfo_t, si_perf_data) != 0x10); 144 + BUILD_BUG_ON(offsetof(compat_siginfo_t, si_perf_type) != 0x14); 146 145 147 146 CHECK_CSI_OFFSET(_sigpoll); 148 147 CHECK_CSI_SIZE (_sigpoll, 2*sizeof(int));
+9 -14
fs/signalfd.c
··· 114 114 break; 115 115 case SIL_FAULT_BNDERR: 116 116 case SIL_FAULT_PKUERR: 117 + case SIL_PERF_EVENT: 117 118 /* 118 - * Fall through to the SIL_FAULT case. Both SIL_FAULT_BNDERR 119 - * and SIL_FAULT_PKUERR are only generated by faults that 120 - * deliver them synchronously to userspace. In case someone 121 - * injects one of these signals and signalfd catches it treat 122 - * it as SIL_FAULT. 119 + * Fall through to the SIL_FAULT case. SIL_FAULT_BNDERR, 120 + * SIL_FAULT_PKUERR, and SIL_PERF_EVENT are only 121 + * generated by faults that deliver them synchronously to 122 + * userspace. In case someone injects one of these signals 123 + * and signalfd catches it treat it as SIL_FAULT. 123 124 */ 124 125 case SIL_FAULT: 125 126 new.ssi_addr = (long) kinfo->si_addr; 126 - #ifdef __ARCH_SI_TRAPNO 127 + break; 128 + case SIL_FAULT_TRAPNO: 129 + new.ssi_addr = (long) kinfo->si_addr; 127 130 new.ssi_trapno = kinfo->si_trapno; 128 - #endif 129 131 break; 130 132 case SIL_FAULT_MCEERR: 131 133 new.ssi_addr = (long) kinfo->si_addr; 132 - #ifdef __ARCH_SI_TRAPNO 133 - new.ssi_trapno = kinfo->si_trapno; 134 - #endif 135 134 new.ssi_addr_lsb = (short) kinfo->si_addr_lsb; 136 - break; 137 - case SIL_PERF_EVENT: 138 - new.ssi_addr = (long) kinfo->si_addr; 139 - new.ssi_perf = kinfo->si_perf; 140 135 break; 141 136 case SIL_CHLD: 142 137 new.ssi_pid = kinfo->si_pid;
+6 -4
include/linux/compat.h
··· 213 213 /* SIGILL, SIGFPE, SIGSEGV, SIGBUS, SIGTRAP, SIGEMT */ 214 214 struct { 215 215 compat_uptr_t _addr; /* faulting insn/memory ref. */ 216 - #ifdef __ARCH_SI_TRAPNO 217 - int _trapno; /* TRAP # which caused the signal */ 218 - #endif 219 216 #define __COMPAT_ADDR_BND_PKEY_PAD (__alignof__(compat_uptr_t) < sizeof(short) ? \ 220 217 sizeof(short) : __alignof__(compat_uptr_t)) 221 218 union { 219 + /* used on alpha and sparc */ 220 + int _trapno; /* TRAP # which caused the signal */ 222 221 /* 223 222 * used when si_code=BUS_MCEERR_AR or 224 223 * used when si_code=BUS_MCEERR_AO ··· 235 236 u32 _pkey; 236 237 } _addr_pkey; 237 238 /* used when si_code=TRAP_PERF */ 238 - compat_ulong_t _perf; 239 + struct { 240 + compat_ulong_t _data; 241 + u32 _type; 242 + } _perf; 239 243 }; 240 244 } _sigfault; 241 245
+1
include/linux/sched/signal.h
··· 326 326 327 327 int force_sig_bnderr(void __user *addr, void __user *lower, void __user *upper); 328 328 int force_sig_pkuerr(void __user *addr, u32 pkey); 329 + int force_sig_perf(void __user *addr, u32 type, u64 sig_data); 329 330 330 331 int force_sig_ptrace_errno_trap(int errno, void __user *addr); 331 332
+1
include/linux/signal.h
··· 40 40 SIL_TIMER, 41 41 SIL_POLL, 42 42 SIL_FAULT, 43 + SIL_FAULT_TRAPNO, 43 44 SIL_FAULT_MCEERR, 44 45 SIL_FAULT_BNDERR, 45 46 SIL_FAULT_PKUERR,
+8 -7
include/uapi/asm-generic/siginfo.h
··· 63 63 /* SIGILL, SIGFPE, SIGSEGV, SIGBUS, SIGTRAP, SIGEMT */ 64 64 struct { 65 65 void __user *_addr; /* faulting insn/memory ref. */ 66 - #ifdef __ARCH_SI_TRAPNO 67 - int _trapno; /* TRAP # which caused the signal */ 68 - #endif 69 66 #ifdef __ia64__ 70 67 int _imm; /* immediate value for "break" */ 71 68 unsigned int _flags; /* see ia64 si_flags */ ··· 72 75 #define __ADDR_BND_PKEY_PAD (__alignof__(void *) < sizeof(short) ? \ 73 76 sizeof(short) : __alignof__(void *)) 74 77 union { 78 + /* used on alpha and sparc */ 79 + int _trapno; /* TRAP # which caused the signal */ 75 80 /* 76 81 * used when si_code=BUS_MCEERR_AR or 77 82 * used when si_code=BUS_MCEERR_AO ··· 91 92 __u32 _pkey; 92 93 } _addr_pkey; 93 94 /* used when si_code=TRAP_PERF */ 94 - unsigned long _perf; 95 + struct { 96 + unsigned long _data; 97 + __u32 _type; 98 + } _perf; 95 99 }; 96 100 } _sigfault; 97 101 ··· 152 150 #define si_int _sifields._rt._sigval.sival_int 153 151 #define si_ptr _sifields._rt._sigval.sival_ptr 154 152 #define si_addr _sifields._sigfault._addr 155 - #ifdef __ARCH_SI_TRAPNO 156 153 #define si_trapno _sifields._sigfault._trapno 157 - #endif 158 154 #define si_addr_lsb _sifields._sigfault._addr_lsb 159 155 #define si_lower _sifields._sigfault._addr_bnd._lower 160 156 #define si_upper _sifields._sigfault._addr_bnd._upper 161 157 #define si_pkey _sifields._sigfault._addr_pkey._pkey 162 - #define si_perf _sifields._sigfault._perf 158 + #define si_perf_data _sifields._sigfault._perf._data 159 + #define si_perf_type _sifields._sigfault._perf._type 163 160 #define si_band _sifields._sigpoll._band 164 161 #define si_fd _sifields._sigpoll._fd 165 162 #define si_call_addr _sifields._sigsys._call_addr
+1 -1
include/uapi/linux/perf_event.h
··· 464 464 465 465 /* 466 466 * User provided data if sigtrap=1, passed back to user via 467 - * siginfo_t::si_perf, e.g. to permit user to identify the event. 467 + * siginfo_t::si_perf_data, e.g. to permit user to identify the event. 468 468 */ 469 469 __u64 sig_data; 470 470 };
+1 -3
include/uapi/linux/signalfd.h
··· 39 39 __s32 ssi_syscall; 40 40 __u64 ssi_call_addr; 41 41 __u32 ssi_arch; 42 - __u32 __pad3; 43 - __u64 ssi_perf; 44 42 45 43 /* 46 44 * Pad strcture to 128 bytes. Remember to update the ··· 49 51 * comes out of a read(2) and we really don't want to have 50 52 * a compat on read(2). 51 53 */ 52 - __u8 __pad[16]; 54 + __u8 __pad[28]; 53 55 }; 54 56 55 57
+2 -9
kernel/events/core.c
··· 6389 6389 6390 6390 static void perf_sigtrap(struct perf_event *event) 6391 6391 { 6392 - struct kernel_siginfo info; 6393 - 6394 6392 /* 6395 6393 * We'd expect this to only occur if the irq_work is delayed and either 6396 6394 * ctx->task or current has changed in the meantime. This can be the ··· 6403 6405 if (current->flags & PF_EXITING) 6404 6406 return; 6405 6407 6406 - clear_siginfo(&info); 6407 - info.si_signo = SIGTRAP; 6408 - info.si_code = TRAP_PERF; 6409 - info.si_errno = event->attr.type; 6410 - info.si_perf = event->attr.sig_data; 6411 - info.si_addr = (void __user *)event->pending_addr; 6412 - force_sig_info(&info); 6408 + force_sig_perf((void __user *)event->pending_addr, 6409 + event->attr.type, event->attr.sig_data); 6413 6410 } 6414 6411 6415 6412 static void perf_pending_event_disable(struct perf_event *event)
+34 -25
kernel/signal.c
··· 1236 1236 case SIL_TIMER: 1237 1237 case SIL_POLL: 1238 1238 case SIL_FAULT: 1239 + case SIL_FAULT_TRAPNO: 1239 1240 case SIL_FAULT_MCEERR: 1240 1241 case SIL_FAULT_BNDERR: 1241 1242 case SIL_FAULT_PKUERR: ··· 1804 1803 return force_sig_info(&info); 1805 1804 } 1806 1805 #endif 1806 + 1807 + int force_sig_perf(void __user *addr, u32 type, u64 sig_data) 1808 + { 1809 + struct kernel_siginfo info; 1810 + 1811 + clear_siginfo(&info); 1812 + info.si_signo = SIGTRAP; 1813 + info.si_errno = 0; 1814 + info.si_code = TRAP_PERF; 1815 + info.si_addr = addr; 1816 + info.si_perf_data = sig_data; 1817 + info.si_perf_type = type; 1818 + 1819 + return force_sig_info(&info); 1820 + } 1807 1821 1808 1822 /* For the crazy architectures that include trap information in 1809 1823 * the errno field, instead of an actual errno value. ··· 2580 2564 { 2581 2565 switch (siginfo_layout(ksig->sig, ksig->info.si_code)) { 2582 2566 case SIL_FAULT: 2567 + case SIL_FAULT_TRAPNO: 2583 2568 case SIL_FAULT_MCEERR: 2584 2569 case SIL_FAULT_BNDERR: 2585 2570 case SIL_FAULT_PKUERR: ··· 3268 3251 #endif 3269 3252 else if ((sig == SIGTRAP) && (si_code == TRAP_PERF)) 3270 3253 layout = SIL_PERF_EVENT; 3254 + #ifdef __ARCH_SI_TRAPNO 3255 + else if (layout == SIL_FAULT) 3256 + layout = SIL_FAULT_TRAPNO; 3257 + #endif 3271 3258 } 3272 3259 else if (si_code <= NSIGPOLL) 3273 3260 layout = SIL_POLL; ··· 3375 3354 break; 3376 3355 case SIL_FAULT: 3377 3356 to->si_addr = ptr_to_compat(from->si_addr); 3378 - #ifdef __ARCH_SI_TRAPNO 3357 + break; 3358 + case SIL_FAULT_TRAPNO: 3359 + to->si_addr = ptr_to_compat(from->si_addr); 3379 3360 to->si_trapno = from->si_trapno; 3380 - #endif 3381 3361 break; 3382 3362 case SIL_FAULT_MCEERR: 3383 3363 to->si_addr = ptr_to_compat(from->si_addr); 3384 - #ifdef __ARCH_SI_TRAPNO 3385 - to->si_trapno = from->si_trapno; 3386 - #endif 3387 3364 to->si_addr_lsb = from->si_addr_lsb; 3388 3365 break; 3389 3366 case SIL_FAULT_BNDERR: 3390 3367 to->si_addr = ptr_to_compat(from->si_addr); 3391 - #ifdef __ARCH_SI_TRAPNO 3392 - to->si_trapno = from->si_trapno; 3393 - #endif 3394 3368 to->si_lower = ptr_to_compat(from->si_lower); 3395 3369 to->si_upper = ptr_to_compat(from->si_upper); 3396 3370 break; 3397 3371 case SIL_FAULT_PKUERR: 3398 3372 to->si_addr = ptr_to_compat(from->si_addr); 3399 - #ifdef __ARCH_SI_TRAPNO 3400 - to->si_trapno = from->si_trapno; 3401 - #endif 3402 3373 to->si_pkey = from->si_pkey; 3403 3374 break; 3404 3375 case SIL_PERF_EVENT: 3405 3376 to->si_addr = ptr_to_compat(from->si_addr); 3406 - to->si_perf = from->si_perf; 3377 + to->si_perf_data = from->si_perf_data; 3378 + to->si_perf_type = from->si_perf_type; 3407 3379 break; 3408 3380 case SIL_CHLD: 3409 3381 to->si_pid = from->si_pid; ··· 3452 3438 break; 3453 3439 case SIL_FAULT: 3454 3440 to->si_addr = compat_ptr(from->si_addr); 3455 - #ifdef __ARCH_SI_TRAPNO 3441 + break; 3442 + case SIL_FAULT_TRAPNO: 3443 + to->si_addr = compat_ptr(from->si_addr); 3456 3444 to->si_trapno = from->si_trapno; 3457 - #endif 3458 3445 break; 3459 3446 case SIL_FAULT_MCEERR: 3460 3447 to->si_addr = compat_ptr(from->si_addr); 3461 - #ifdef __ARCH_SI_TRAPNO 3462 - to->si_trapno = from->si_trapno; 3463 - #endif 3464 3448 to->si_addr_lsb = from->si_addr_lsb; 3465 3449 break; 3466 3450 case SIL_FAULT_BNDERR: 3467 3451 to->si_addr = compat_ptr(from->si_addr); 3468 - #ifdef __ARCH_SI_TRAPNO 3469 - to->si_trapno = from->si_trapno; 3470 - #endif 3471 3452 to->si_lower = compat_ptr(from->si_lower); 3472 3453 to->si_upper = compat_ptr(from->si_upper); 3473 3454 break; 3474 3455 case SIL_FAULT_PKUERR: 3475 3456 to->si_addr = compat_ptr(from->si_addr); 3476 - #ifdef __ARCH_SI_TRAPNO 3477 - to->si_trapno = from->si_trapno; 3478 - #endif 3479 3457 to->si_pkey = from->si_pkey; 3480 3458 break; 3481 3459 case SIL_PERF_EVENT: 3482 3460 to->si_addr = compat_ptr(from->si_addr); 3483 - to->si_perf = from->si_perf; 3461 + to->si_perf_data = from->si_perf_data; 3462 + to->si_perf_type = from->si_perf_type; 3484 3463 break; 3485 3464 case SIL_CHLD: 3486 3465 to->si_pid = from->si_pid; ··· 4651 4644 4652 4645 /* sigfault */ 4653 4646 CHECK_OFFSET(si_addr); 4647 + CHECK_OFFSET(si_trapno); 4654 4648 CHECK_OFFSET(si_addr_lsb); 4655 4649 CHECK_OFFSET(si_lower); 4656 4650 CHECK_OFFSET(si_upper); 4657 4651 CHECK_OFFSET(si_pkey); 4658 - CHECK_OFFSET(si_perf); 4652 + CHECK_OFFSET(si_perf_data); 4653 + CHECK_OFFSET(si_perf_type); 4659 4654 4660 4655 /* sigpoll */ 4661 4656 CHECK_OFFSET(si_band);
+7 -7
tools/testing/selftests/perf_events/sigtrap_threads.c
··· 43 43 siginfo_t first_siginfo; /* First observed siginfo_t. */ 44 44 } ctx; 45 45 46 - /* Unique value to check si_perf is correctly set from perf_event_attr::sig_data. */ 46 + /* Unique value to check si_perf_data is correctly set from perf_event_attr::sig_data. */ 47 47 #define TEST_SIG_DATA(addr) (~(unsigned long)(addr)) 48 48 49 49 static struct perf_event_attr make_event_attr(bool enabled, volatile void *addr) ··· 164 164 EXPECT_EQ(ctx.signal_count, NUM_THREADS); 165 165 EXPECT_EQ(ctx.tids_want_signal, 0); 166 166 EXPECT_EQ(ctx.first_siginfo.si_addr, &ctx.iterate_on); 167 - EXPECT_EQ(ctx.first_siginfo.si_errno, PERF_TYPE_BREAKPOINT); 168 - EXPECT_EQ(ctx.first_siginfo.si_perf, TEST_SIG_DATA(&ctx.iterate_on)); 167 + EXPECT_EQ(ctx.first_siginfo.si_perf_type, PERF_TYPE_BREAKPOINT); 168 + EXPECT_EQ(ctx.first_siginfo.si_perf_data, TEST_SIG_DATA(&ctx.iterate_on)); 169 169 170 170 /* Check enabled for parent. */ 171 171 ctx.iterate_on = 0; ··· 183 183 EXPECT_EQ(ctx.signal_count, NUM_THREADS); 184 184 EXPECT_EQ(ctx.tids_want_signal, 0); 185 185 EXPECT_EQ(ctx.first_siginfo.si_addr, &ctx.iterate_on); 186 - EXPECT_EQ(ctx.first_siginfo.si_errno, PERF_TYPE_BREAKPOINT); 187 - EXPECT_EQ(ctx.first_siginfo.si_perf, TEST_SIG_DATA(&ctx.iterate_on)); 186 + EXPECT_EQ(ctx.first_siginfo.si_perf_type, PERF_TYPE_BREAKPOINT); 187 + EXPECT_EQ(ctx.first_siginfo.si_perf_data, TEST_SIG_DATA(&ctx.iterate_on)); 188 188 189 189 /* Check enabled for parent. */ 190 190 ctx.iterate_on = 0; ··· 203 203 EXPECT_EQ(ctx.signal_count, NUM_THREADS * ctx.iterate_on); 204 204 EXPECT_EQ(ctx.tids_want_signal, 0); 205 205 EXPECT_EQ(ctx.first_siginfo.si_addr, &ctx.iterate_on); 206 - EXPECT_EQ(ctx.first_siginfo.si_errno, PERF_TYPE_BREAKPOINT); 207 - EXPECT_EQ(ctx.first_siginfo.si_perf, TEST_SIG_DATA(&ctx.iterate_on)); 206 + EXPECT_EQ(ctx.first_siginfo.si_perf_type, PERF_TYPE_BREAKPOINT); 207 + EXPECT_EQ(ctx.first_siginfo.si_perf_data, TEST_SIG_DATA(&ctx.iterate_on)); 208 208 } 209 209 210 210 TEST_HARNESS_MAIN