#include <linux/timekeeping.h>
 #include <linux/sysctl.h>
 #include <linux/elf.h>
+#include <linux/pidfs.h>
+#include <uapi/linux/pidfd.h>
 
 #include <linux/uaccess.h>
 #include <asm/mmu_context.h>
 #define CORE_FILE_NOTE_SIZE_DEFAULT (4*1024*1024)
 /* Define a reasonable max cap */
 #define CORE_FILE_NOTE_SIZE_MAX (16*1024*1024)
+/*
+ * File descriptor number for the pidfd for the thread-group leader of
+ * the coredumping task installed into the usermode helper's file
+ * descriptor table.
+ */
+#define COREDUMP_PIDFD_NUMBER 3
 
 static int core_uses_pid;
 static unsigned int core_pipe_limit;
                        case 'C':
                                err = cn_printf(cn, "%d", cprm->cpu);
                                break;
+                       /* pidfd number */
+                       case 'F': {
+                               /*
+                                * Installing a pidfd only makes sense if
+                                * we actually spawn a usermode helper.
+                                */
+                               if (!ispipe)
+                                       break;
+
+                               /*
+                                * Note that we'll install a pidfd for the
+                                * thread-group leader. We know that task
+                                * linkage hasn't been removed yet and even if
+                                * this @current isn't the actual thread-group
+                                * leader we know that the thread-group leader
+                                * cannot be reaped until @current has exited.
+                                */
+                               cprm->pid = task_tgid(current);
+                               err = cn_printf(cn, "%d", COREDUMP_PIDFD_NUMBER);
+                               break;
+                       }
                        default:
                                break;
                        }
 }
 
 /*
- * umh_pipe_setup
+ * umh_coredump_setup
  * helper function to customize the process used
  * to collect the core in userspace.  Specifically
  * it sets up a pipe and installs it as fd 0 (stdin)
  * is a special value that we use to trap recursive
  * core dumps
  */
-static int umh_pipe_setup(struct subprocess_info *info, struct cred *new)
+static int umh_coredump_setup(struct subprocess_info *info, struct cred *new)
 {
        struct file *files[2];
        struct coredump_params *cp = (struct coredump_params *)info->data;
        int err;
 
+       if (cp->pid) {
+               struct file *pidfs_file __free(fput) = NULL;
+
+               pidfs_file = pidfs_alloc_file(cp->pid, 0);
+               if (IS_ERR(pidfs_file))
+                       return PTR_ERR(pidfs_file);
+
+               /*
+                * Usermode helpers are childen of either
+                * system_unbound_wq or of kthreadd. So we know that
+                * we're starting off with a clean file descriptor
+                * table. So we should always be able to use
+                * COREDUMP_PIDFD_NUMBER as our file descriptor value.
+                */
+               err = replace_fd(COREDUMP_PIDFD_NUMBER, pidfs_file, 0);
+               if (err < 0)
+                       return err;
+       }
+
        err = create_pipe_files(files, 0);
        if (err)
                return err;
                }
 
                if (cprm.limit == 1) {
-                       /* See umh_pipe_setup() which sets RLIMIT_CORE = 1.
+                       /* See umh_coredump_setup() which sets RLIMIT_CORE = 1.
                         *
                         * Normally core limits are irrelevant to pipes, since
                         * we're not writing to the file system, but we use
                retval = -ENOMEM;
                sub_info = call_usermodehelper_setup(helper_argv[0],
                                                helper_argv, NULL, GFP_KERNEL,
-                                               umh_pipe_setup, NULL, &cprm);
+                                               umh_coredump_setup, NULL, &cprm);
                if (sub_info)
                        retval = call_usermodehelper_exec(sub_info,
                                                          UMH_WAIT_EXEC);