History

pidfd: add a new supported_mask field

Some of the future fields in struct pidfd_info can be optional. If the kernel has nothing to emit in that field, then it doesn't set the flag in the reply. This presents a problem: There is currently no way to know what mask flags the kernel supports since one can't always count on them being in the reply. Add a new PIDFD_INFO_SUPPORTED_MASK flag and field that the kernel can set in the reply. Userspace can use this to determine if the fields it requires from the kernel are supported. This also gives us a way to deprecate fields in the future, if that should become necessary.

Christian Brauner committed 1 year ago

Commit dfd78541 parent d8fc51d2 files · +19 −1Browse files

Unified · Split

2 files
  1. fs/pidfs.c +16 −1
  2. include/uapi/linux/pidfd.h +3 −0
fs/pidfs.c+16−1
@@ -293,6 +293,14 @@ static __u32 pidfs_coredump_mask(unsigned long mm_flags) · 292 unmodified lines
293 return 0;293 return 0;
294}294}
295 295
296/* This must be updated whenever a new flag is added */
297#define PIDFD_INFO_SUPPORTED (PIDFD_INFO_PID | \
298 PIDFD_INFO_CREDS | \
299 PIDFD_INFO_CGROUPID | \
300 PIDFD_INFO_EXIT | \
301 PIDFD_INFO_COREDUMP | \
302 PIDFD_INFO_SUPPORTED_MASK)
303
296static long pidfd_info(struct file *file, unsigned int cmd, unsigned long arg)304static long pidfd_info(struct file *file, unsigned int cmd, unsigned long arg)
297{305{
298 struct pidfd_info __user *uinfo = (struct pidfd_info __user *)arg;306 struct pidfd_info __user *uinfo = (struct pidfd_info __user *)arg;
@@ -306,7 +314,7 @@ static long pidfd_info(struct file *file, unsigned int cmd, unsigned long arg) · 7 unmodified lines
306 const struct cred *c;314 const struct cred *c;
307 __u64 mask;315 __u64 mask;
308 316
309 BUILD_BUG_ON(sizeof(struct pidfd_info) != PIDFD_INFO_SIZE_VER1);317 BUILD_BUG_ON(sizeof(struct pidfd_info) != PIDFD_INFO_SIZE_VER2);
310 318
311 if (!uinfo)319 if (!uinfo)
312 return -EINVAL;320 return -EINVAL;
@@ -412,6 +420,13 @@ static long pidfd_info(struct file *file, unsigned int cmd, unsigned long arg) · 99 unmodified lines
412 return -ESRCH;420 return -ESRCH;
413 421
414copy_out:422copy_out:
423 if (mask & PIDFD_INFO_SUPPORTED_MASK) {
424 kinfo.mask |= PIDFD_INFO_SUPPORTED_MASK;
425 kinfo.supported_mask = PIDFD_INFO_SUPPORTED;
426 }
427
428 /* Are there bits in the return mask not present in PIDFD_INFO_SUPPORTED? */
429 WARN_ON_ONCE(~PIDFD_INFO_SUPPORTED & kinfo.mask);
415 /*430 /*
416 * If userspace and the kernel have the same struct size it can just431 * If userspace and the kernel have the same struct size it can just
417 * be copied. If userspace provides an older struct, only the bits that432 * be copied. If userspace provides an older struct, only the bits that
include/uapi/linux/pidfd.h+3−0
@@ -26,9 +26,11 @@ · 25 unmodified lines
26#define PIDFD_INFO_CGROUPID (1UL << 2) /* Always returned if available, even if not requested */26#define PIDFD_INFO_CGROUPID (1UL << 2) /* Always returned if available, even if not requested */
27#define PIDFD_INFO_EXIT (1UL << 3) /* Only returned if requested. */27#define PIDFD_INFO_EXIT (1UL << 3) /* Only returned if requested. */
28#define PIDFD_INFO_COREDUMP (1UL << 4) /* Only returned if requested. */28#define PIDFD_INFO_COREDUMP (1UL << 4) /* Only returned if requested. */
29#define PIDFD_INFO_SUPPORTED_MASK (1UL << 5) /* Want/got supported mask flags */
29 30
30#define PIDFD_INFO_SIZE_VER0 64 /* sizeof first published struct */31#define PIDFD_INFO_SIZE_VER0 64 /* sizeof first published struct */
31#define PIDFD_INFO_SIZE_VER1 72 /* sizeof second published struct */32#define PIDFD_INFO_SIZE_VER1 72 /* sizeof second published struct */
33#define PIDFD_INFO_SIZE_VER2 80 /* sizeof third published struct */
32 34
33/*35/*
34 * Values for @coredump_mask in pidfd_info.36 * Values for @coredump_mask in pidfd_info.
@@ -94,6 +96,7 @@ struct pidfd_info { · 59 unmodified lines
94 __s32 exit_code;96 __s32 exit_code;
95 __u32 coredump_mask;97 __u32 coredump_mask;
96 __u32 __spare1;98 __u32 __spare1;
99 __u64 supported_mask; /* Mask flags that this kernel supports */
97};100};
98 101
99#define PIDFS_IOCTL_MAGIC 0xFF102#define PIDFS_IOCTL_MAGIC 0xFF