summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--fs/pidfs.c12
-rw-r--r--include/uapi/linux/pidfd.h4
2 files changed, 12 insertions, 4 deletions
diff --git a/fs/pidfs.c b/fs/pidfs.c
index a8d1bca0395d..2acf84670578 100644
--- a/fs/pidfs.c
+++ b/fs/pidfs.c
@@ -57,6 +57,7 @@ struct pidfs_attr {
};
__u32 coredump_mask;
__u32 coredump_signal;
+ __u32 coredump_code;
};
static struct rhashtable pidfs_ino_ht;
@@ -333,7 +334,8 @@ static __u32 pidfs_coredump_mask(unsigned long mm_flags)
PIDFD_INFO_EXIT | \
PIDFD_INFO_COREDUMP | \
PIDFD_INFO_SUPPORTED_MASK | \
- PIDFD_INFO_COREDUMP_SIGNAL)
+ PIDFD_INFO_COREDUMP_SIGNAL | \
+ PIDFD_INFO_COREDUMP_CODE)
static long pidfd_info(struct file *file, unsigned int cmd, unsigned long arg)
{
@@ -347,7 +349,7 @@ static long pidfd_info(struct file *file, unsigned int cmd, unsigned long arg)
const struct cred *c;
__u64 mask;
- BUILD_BUG_ON(sizeof(struct pidfd_info) != PIDFD_INFO_SIZE_VER2);
+ BUILD_BUG_ON(sizeof(struct pidfd_info) != PIDFD_INFO_SIZE_VER3);
if (!uinfo)
return -EINVAL;
@@ -380,9 +382,10 @@ static long pidfd_info(struct file *file, unsigned int cmd, unsigned long arg)
if (mask & PIDFD_INFO_COREDUMP) {
if (test_bit(PIDFS_ATTR_BIT_COREDUMP, &attr->attr_mask)) {
smp_rmb();
- kinfo.mask |= PIDFD_INFO_COREDUMP | PIDFD_INFO_COREDUMP_SIGNAL;
+ kinfo.mask |= PIDFD_INFO_COREDUMP | PIDFD_INFO_COREDUMP_SIGNAL | PIDFD_INFO_COREDUMP_CODE;
kinfo.coredump_mask = attr->coredump_mask;
kinfo.coredump_signal = attr->coredump_signal;
+ kinfo.coredump_code = attr->coredump_code;
}
}
@@ -755,8 +758,9 @@ void pidfs_coredump(const struct coredump_params *cprm)
PIDFD_COREDUMPED;
/* If coredumping is set to skip we should never end up here. */
VFS_WARN_ON_ONCE(attr->coredump_mask & PIDFD_COREDUMP_SKIP);
- /* Expose the signal number that caused the coredump. */
+ /* Expose the signal number and code that caused the coredump. */
attr->coredump_signal = cprm->siginfo->si_signo;
+ attr->coredump_code = cprm->siginfo->si_code;
smp_wmb();
set_bit(PIDFS_ATTR_BIT_COREDUMP, &attr->attr_mask);
}
diff --git a/include/uapi/linux/pidfd.h b/include/uapi/linux/pidfd.h
index 9281956a9f32..0919246a1611 100644
--- a/include/uapi/linux/pidfd.h
+++ b/include/uapi/linux/pidfd.h
@@ -29,10 +29,12 @@
#define PIDFD_INFO_COREDUMP (1UL << 4) /* Only returned if requested. */
#define PIDFD_INFO_SUPPORTED_MASK (1UL << 5) /* Want/got supported mask flags */
#define PIDFD_INFO_COREDUMP_SIGNAL (1UL << 6) /* Always returned if PIDFD_INFO_COREDUMP is requested. */
+#define PIDFD_INFO_COREDUMP_CODE (1UL << 7) /* Always returned if PIDFD_INFO_COREDUMP is requested. */
#define PIDFD_INFO_SIZE_VER0 64 /* sizeof first published struct */
#define PIDFD_INFO_SIZE_VER1 72 /* sizeof second published struct */
#define PIDFD_INFO_SIZE_VER2 80 /* sizeof third published struct */
+#define PIDFD_INFO_SIZE_VER3 88 /* sizeof fourth published struct */
/*
* Values for @coredump_mask in pidfd_info.
@@ -99,6 +101,8 @@ struct pidfd_info {
struct /* coredump info */ {
__u32 coredump_mask;
__u32 coredump_signal;
+ __u32 coredump_code;
+ __u32 coredump_pad; /* align supported_mask to 8 bytes */
};
__u64 supported_mask; /* Mask flags that this kernel supports */
};