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

Configure Feed

Select the types of activity you want to include in your feed.

pidfs: expose coredump signal

Userspace needs access to the signal that caused the coredump before the
coredumping process has been reaped. Expose it as part of the coredump
information in struct pidfd_info. After the process has been reaped that
info is also available as part of PIDFD_INFO_EXIT's exit_code field.

Link: https://patch.msgid.link/20251028-work-coredump-signal-v1-8-ca449b7b7aa0@kernel.org
Reviewed-by: Alexander Mikhalitsyn <aleksandr.mikhalitsyn@canonical.com>
Reviewed-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Christian Brauner <brauner@kernel.org>

+24 -13
+19 -11
fs/pidfs.c
··· 41 41 42 42 enum pidfs_attr_mask_bits { 43 43 PIDFS_ATTR_BIT_EXIT = 0, 44 + PIDFS_ATTR_BIT_COREDUMP = 1, 44 45 }; 45 46 46 47 struct pidfs_attr { ··· 52 51 __s32 exit_code; 53 52 }; 54 53 __u32 coredump_mask; 54 + __u32 coredump_signal; 55 55 }; 56 56 57 57 static struct rb_root pidfs_ino_tree = RB_ROOT; ··· 299 297 PIDFD_INFO_CGROUPID | \ 300 298 PIDFD_INFO_EXIT | \ 301 299 PIDFD_INFO_COREDUMP | \ 302 - PIDFD_INFO_SUPPORTED_MASK) 300 + PIDFD_INFO_SUPPORTED_MASK | \ 301 + PIDFD_INFO_COREDUMP_SIGNAL) 303 302 304 303 static long pidfd_info(struct file *file, unsigned int cmd, unsigned long arg) 305 304 { ··· 345 342 } 346 343 347 344 if (mask & PIDFD_INFO_COREDUMP) { 348 - kinfo.coredump_mask = READ_ONCE(attr->coredump_mask); 349 - if (kinfo.coredump_mask) 350 - kinfo.mask |= PIDFD_INFO_COREDUMP; 345 + if (test_bit(PIDFS_ATTR_BIT_COREDUMP, &attr->attr_mask)) { 346 + smp_rmb(); 347 + kinfo.mask |= PIDFD_INFO_COREDUMP | PIDFD_INFO_COREDUMP_SIGNAL; 348 + kinfo.coredump_mask = attr->coredump_mask; 349 + kinfo.coredump_signal = attr->coredump_signal; 350 + } 351 351 } 352 352 353 353 task = get_pid_task(pid, PIDTYPE_PID); ··· 376 370 377 371 kinfo.coredump_mask = pidfs_coredump_mask(flags); 378 372 kinfo.mask |= PIDFD_INFO_COREDUMP; 373 + /* No coredump actually took place, so no coredump signal. */ 379 374 } 380 375 } 381 376 ··· 673 666 { 674 667 struct pid *pid = cprm->pid; 675 668 struct pidfs_attr *attr; 676 - __u32 coredump_mask = 0; 677 669 678 670 attr = READ_ONCE(pid->attr); 679 671 680 672 VFS_WARN_ON_ONCE(!attr); 681 673 VFS_WARN_ON_ONCE(attr == PIDFS_PID_DEAD); 682 674 683 - /* Note how we were coredumped. */ 684 - coredump_mask = pidfs_coredump_mask(cprm->mm_flags); 685 - /* Note that we actually did coredump. */ 686 - coredump_mask |= PIDFD_COREDUMPED; 675 + /* Note how we were coredumped and that we coredumped. */ 676 + attr->coredump_mask = pidfs_coredump_mask(cprm->mm_flags) | 677 + PIDFD_COREDUMPED; 687 678 /* If coredumping is set to skip we should never end up here. */ 688 - VFS_WARN_ON_ONCE(coredump_mask & PIDFD_COREDUMP_SKIP); 689 - smp_store_release(&attr->coredump_mask, coredump_mask); 679 + VFS_WARN_ON_ONCE(attr->coredump_mask & PIDFD_COREDUMP_SKIP); 680 + /* Expose the signal number that caused the coredump. */ 681 + attr->coredump_signal = cprm->siginfo->si_signo; 682 + smp_wmb(); 683 + set_bit(PIDFS_ATTR_BIT_COREDUMP, &attr->attr_mask); 690 684 } 691 685 #endif 692 686
+5 -2
include/uapi/linux/pidfd.h
··· 27 27 #define PIDFD_INFO_EXIT (1UL << 3) /* Only returned if requested. */ 28 28 #define PIDFD_INFO_COREDUMP (1UL << 4) /* Only returned if requested. */ 29 29 #define PIDFD_INFO_SUPPORTED_MASK (1UL << 5) /* Want/got supported mask flags */ 30 + #define PIDFD_INFO_COREDUMP_SIGNAL (1UL << 6) /* Always returned if PIDFD_INFO_COREDUMP is requested. */ 30 31 31 32 #define PIDFD_INFO_SIZE_VER0 64 /* sizeof first published struct */ 32 33 #define PIDFD_INFO_SIZE_VER1 72 /* sizeof second published struct */ ··· 95 94 __u32 fsuid; 96 95 __u32 fsgid; 97 96 __s32 exit_code; 98 - __u32 coredump_mask; 99 - __u32 __spare1; 97 + struct /* coredump info */ { 98 + __u32 coredump_mask; 99 + __u32 coredump_signal; 100 + }; 100 101 __u64 supported_mask; /* Mask flags that this kernel supports */ 101 102 }; 102 103