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.

pidfds: add coredump_code field to pidfd_info

The struct pidfd_info currently exposes in a field called coredump_signal the
signal number (si_signo) that triggered the dump (for example, 11 for SIGSEGV).
However, it is also valuable to understand the reason why that signal was sent.
This additional context is provided by the signal code (si_code), such as 2 for
SEGV_ACCERR.

Add a new field to struct pidfd_info called coredump_code with the value of
si_code for the benefit of sysadmins who pipe core dumps to user-space programs
for later analysis. The following snippet illustrates a simplified C program
that consumes coredump_signal and coredump_code, and then logs core dump
signals and codes to a file:

int pidfd = (int)atoi(argv[1]);

struct pidfd_info info = {
.mask = PIDFD_INFO_EXIT | PIDFD_INFO_COREDUMP,
};

if (ioctl(pidfd, PIDFD_GET_INFO, &info) == 0)
if (info.mask & PIDFD_INFO_COREDUMP)
fprintf(f, "PID=%d, si_signo: %d si_code: %d\n",
info.pid, info.coredump_signal, info.coredump_code);

Assuming the program is installed under /usr/local/bin/core-logger, core dump
processing can be enabled by setting /proc/sys/kernel/core_pattern to
'|/usr/local/bin/dumpstuff %F'.

systemd-coredump(8) already uses pidfds to process core dumps, and it could be
extended to include the values of coredump_code too.

Signed-off-by: Emanuele Rocca <emanuele.rocca@arm.com>
Link: https://patch.msgid.link/acE52HIFivNZN3nE@NH27D9T0LF
Acked-by: Oleg Nesterov <oleg@redhat.com>
Signed-off-by: Christian Brauner <brauner@kernel.org>

authored by

Emanuele Rocca and committed by
Christian Brauner
701f7f4f 3fc66a10

+12 -4
+8 -4
fs/pidfs.c
··· 57 57 }; 58 58 __u32 coredump_mask; 59 59 __u32 coredump_signal; 60 + __u32 coredump_code; 60 61 }; 61 62 62 63 static struct rhashtable pidfs_ino_ht; ··· 334 333 PIDFD_INFO_EXIT | \ 335 334 PIDFD_INFO_COREDUMP | \ 336 335 PIDFD_INFO_SUPPORTED_MASK | \ 337 - PIDFD_INFO_COREDUMP_SIGNAL) 336 + PIDFD_INFO_COREDUMP_SIGNAL | \ 337 + PIDFD_INFO_COREDUMP_CODE) 338 338 339 339 static long pidfd_info(struct file *file, unsigned int cmd, unsigned long arg) 340 340 { ··· 349 347 const struct cred *c; 350 348 __u64 mask; 351 349 352 - BUILD_BUG_ON(sizeof(struct pidfd_info) != PIDFD_INFO_SIZE_VER2); 350 + BUILD_BUG_ON(sizeof(struct pidfd_info) != PIDFD_INFO_SIZE_VER3); 353 351 354 352 if (!uinfo) 355 353 return -EINVAL; ··· 382 380 if (mask & PIDFD_INFO_COREDUMP) { 383 381 if (test_bit(PIDFS_ATTR_BIT_COREDUMP, &attr->attr_mask)) { 384 382 smp_rmb(); 385 - kinfo.mask |= PIDFD_INFO_COREDUMP | PIDFD_INFO_COREDUMP_SIGNAL; 383 + kinfo.mask |= PIDFD_INFO_COREDUMP | PIDFD_INFO_COREDUMP_SIGNAL | PIDFD_INFO_COREDUMP_CODE; 386 384 kinfo.coredump_mask = attr->coredump_mask; 387 385 kinfo.coredump_signal = attr->coredump_signal; 386 + kinfo.coredump_code = attr->coredump_code; 388 387 } 389 388 } 390 389 ··· 758 755 PIDFD_COREDUMPED; 759 756 /* If coredumping is set to skip we should never end up here. */ 760 757 VFS_WARN_ON_ONCE(attr->coredump_mask & PIDFD_COREDUMP_SKIP); 761 - /* Expose the signal number that caused the coredump. */ 758 + /* Expose the signal number and code that caused the coredump. */ 762 759 attr->coredump_signal = cprm->siginfo->si_signo; 760 + attr->coredump_code = cprm->siginfo->si_code; 763 761 smp_wmb(); 764 762 set_bit(PIDFS_ATTR_BIT_COREDUMP, &attr->attr_mask); 765 763 }
+4
include/uapi/linux/pidfd.h
··· 29 29 #define PIDFD_INFO_COREDUMP (1UL << 4) /* Only returned if requested. */ 30 30 #define PIDFD_INFO_SUPPORTED_MASK (1UL << 5) /* Want/got supported mask flags */ 31 31 #define PIDFD_INFO_COREDUMP_SIGNAL (1UL << 6) /* Always returned if PIDFD_INFO_COREDUMP is requested. */ 32 + #define PIDFD_INFO_COREDUMP_CODE (1UL << 7) /* Always returned if PIDFD_INFO_COREDUMP is requested. */ 32 33 33 34 #define PIDFD_INFO_SIZE_VER0 64 /* sizeof first published struct */ 34 35 #define PIDFD_INFO_SIZE_VER1 72 /* sizeof second published struct */ 35 36 #define PIDFD_INFO_SIZE_VER2 80 /* sizeof third published struct */ 37 + #define PIDFD_INFO_SIZE_VER3 88 /* sizeof fourth published struct */ 36 38 37 39 /* 38 40 * Values for @coredump_mask in pidfd_info. ··· 101 99 struct /* coredump info */ { 102 100 __u32 coredump_mask; 103 101 __u32 coredump_signal; 102 + __u32 coredump_code; 103 + __u32 coredump_pad; /* align supported_mask to 8 bytes */ 104 104 }; 105 105 __u64 supported_mask; /* Mask flags that this kernel supports */ 106 106 };