Skip to content

Commit 701f7f4

Browse files
emabrauner
authored andcommitted
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>
1 parent 3fc66a1 commit 701f7f4

2 files changed

Lines changed: 12 additions & 4 deletions

File tree

fs/pidfs.c

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ struct pidfs_attr {
5757
};
5858
__u32 coredump_mask;
5959
__u32 coredump_signal;
60+
__u32 coredump_code;
6061
};
6162

6263
static struct rhashtable pidfs_ino_ht;
@@ -333,7 +334,8 @@ static __u32 pidfs_coredump_mask(unsigned long mm_flags)
333334
PIDFD_INFO_EXIT | \
334335
PIDFD_INFO_COREDUMP | \
335336
PIDFD_INFO_SUPPORTED_MASK | \
336-
PIDFD_INFO_COREDUMP_SIGNAL)
337+
PIDFD_INFO_COREDUMP_SIGNAL | \
338+
PIDFD_INFO_COREDUMP_CODE)
337339

338340
static long pidfd_info(struct file *file, unsigned int cmd, unsigned long arg)
339341
{
@@ -347,7 +349,7 @@ static long pidfd_info(struct file *file, unsigned int cmd, unsigned long arg)
347349
const struct cred *c;
348350
__u64 mask;
349351

350-
BUILD_BUG_ON(sizeof(struct pidfd_info) != PIDFD_INFO_SIZE_VER2);
352+
BUILD_BUG_ON(sizeof(struct pidfd_info) != PIDFD_INFO_SIZE_VER3);
351353

352354
if (!uinfo)
353355
return -EINVAL;
@@ -380,9 +382,10 @@ static long pidfd_info(struct file *file, unsigned int cmd, unsigned long arg)
380382
if (mask & PIDFD_INFO_COREDUMP) {
381383
if (test_bit(PIDFS_ATTR_BIT_COREDUMP, &attr->attr_mask)) {
382384
smp_rmb();
383-
kinfo.mask |= PIDFD_INFO_COREDUMP | PIDFD_INFO_COREDUMP_SIGNAL;
385+
kinfo.mask |= PIDFD_INFO_COREDUMP | PIDFD_INFO_COREDUMP_SIGNAL | PIDFD_INFO_COREDUMP_CODE;
384386
kinfo.coredump_mask = attr->coredump_mask;
385387
kinfo.coredump_signal = attr->coredump_signal;
388+
kinfo.coredump_code = attr->coredump_code;
386389
}
387390
}
388391

@@ -755,8 +758,9 @@ void pidfs_coredump(const struct coredump_params *cprm)
755758
PIDFD_COREDUMPED;
756759
/* If coredumping is set to skip we should never end up here. */
757760
VFS_WARN_ON_ONCE(attr->coredump_mask & PIDFD_COREDUMP_SKIP);
758-
/* Expose the signal number that caused the coredump. */
761+
/* Expose the signal number and code that caused the coredump. */
759762
attr->coredump_signal = cprm->siginfo->si_signo;
763+
attr->coredump_code = cprm->siginfo->si_code;
760764
smp_wmb();
761765
set_bit(PIDFS_ATTR_BIT_COREDUMP, &attr->attr_mask);
762766
}

include/uapi/linux/pidfd.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,12 @@
2929
#define PIDFD_INFO_COREDUMP (1UL << 4) /* Only returned if requested. */
3030
#define PIDFD_INFO_SUPPORTED_MASK (1UL << 5) /* Want/got supported mask flags */
3131
#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. */
3233

3334
#define PIDFD_INFO_SIZE_VER0 64 /* sizeof first published struct */
3435
#define PIDFD_INFO_SIZE_VER1 72 /* sizeof second published struct */
3536
#define PIDFD_INFO_SIZE_VER2 80 /* sizeof third published struct */
37+
#define PIDFD_INFO_SIZE_VER3 88 /* sizeof fourth published struct */
3638

3739
/*
3840
* Values for @coredump_mask in pidfd_info.
@@ -99,6 +101,8 @@ struct pidfd_info {
99101
struct /* coredump info */ {
100102
__u32 coredump_mask;
101103
__u32 coredump_signal;
104+
__u32 coredump_code;
105+
__u32 coredump_pad; /* align supported_mask to 8 bytes */
102106
};
103107
__u64 supported_mask; /* Mask flags that this kernel supports */
104108
};

0 commit comments

Comments
 (0)