]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
sched/coredump: introduce enum task_dumpable
authorChristian Brauner (Amutable) <brauner@kernel.org>
Wed, 20 May 2026 21:48:52 +0000 (23:48 +0200)
committerChristian Brauner <brauner@kernel.org>
Tue, 26 May 2026 09:02:01 +0000 (11:02 +0200)
Replace the SUID_DUMP_DISABLE/USER/ROOT preprocessor constants with
enum task_dumpable.  Numeric values are preserved (kernel.suid_dumpable
sysctl and prctl(PR_SET_DUMPABLE) ABI), so this is a pure rename with
no behavioral change.

Subsequent commits relocate dumpability onto a per-task structure
where the enum type will allow stronger type-checking on the new API.

Reviewed-by: Jann Horn <jannh@google.com>
Reviewed-by: David Hildenbrand (arm) <david@kernel.org>
Link: https://patch.msgid.link/20260520-work-task_exec_state-v3-1-69f895bc1385@kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
arch/arm64/kernel/mte.c
fs/coredump.c
fs/exec.c
fs/pidfs.c
fs/proc/base.c
include/linux/mm_types.h
include/linux/sched/coredump.h
kernel/exit.c
kernel/ptrace.c
kernel/sys.c

index 6874b16d0657676a57ba14be8fdd6f5d7659a278..904ac41f93bc373e0e4aa3c5e15d4a5b98c42f07 100644 (file)
@@ -538,7 +538,7 @@ static int access_remote_tags(struct task_struct *tsk, unsigned long addr,
                return -EPERM;
 
        if (!tsk->ptrace || (current != tsk->parent) ||
-           ((get_dumpable(mm) != SUID_DUMP_USER) &&
+           ((get_dumpable(mm) != TASK_DUMPABLE_OWNER) &&
             !ptracer_capable(tsk, mm->user_ns))) {
                mmput(mm);
                return -EPERM;
index bb6fdb1f458e9b855c76b1a0f8c2e801d204b7cb..f5348d5bc441ce56bd6279938c7a6506df246ce4 100644 (file)
@@ -873,7 +873,7 @@ static inline bool coredump_socket(struct core_name *cn, struct coredump_params
 static inline bool coredump_force_suid_safe(const struct coredump_params *cprm)
 {
        /* Require nonrelative corefile path and be extra careful. */
-       return __get_dumpable(cprm->mm_flags) == SUID_DUMP_ROOT;
+       return __get_dumpable(cprm->mm_flags) == TASK_DUMPABLE_ROOT;
 }
 
 static bool coredump_file(struct core_name *cn, struct coredump_params *cprm,
@@ -1419,7 +1419,7 @@ EXPORT_SYMBOL(dump_align);
 
 void validate_coredump_safety(void)
 {
-       if (suid_dumpable == SUID_DUMP_ROOT &&
+       if (suid_dumpable == TASK_DUMPABLE_ROOT &&
            core_pattern[0] != '/' && core_pattern[0] != '|' && core_pattern[0] != '@') {
 
                coredump_report_failure("Unsafe core_pattern used with fs.suid_dumpable=2: "
index ba12b4c466f6daf48cdc898e59c062341e400e36..f5663bb607d3e907a54c3ac72e3228ad1a962f19 100644 (file)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1212,7 +1212,7 @@ int begin_new_exec(struct linux_binprm * bprm)
              gid_eq(current_egid(), current_gid())))
                set_dumpable(current->mm, suid_dumpable);
        else
-               set_dumpable(current->mm, SUID_DUMP_USER);
+               set_dumpable(current->mm, TASK_DUMPABLE_OWNER);
 
        perf_event_exec();
 
@@ -1261,7 +1261,7 @@ int begin_new_exec(struct linux_binprm * bprm)
         * wait until new credentials are committed
         * by commit_creds() above
         */
-       if (get_dumpable(me->mm) != SUID_DUMP_USER)
+       if (get_dumpable(me->mm) != TASK_DUMPABLE_OWNER)
                perf_event_exit_task(me);
        /*
         * cred_guard_mutex must be held at least to this point to prevent
@@ -1906,11 +1906,11 @@ void set_binfmt(struct linux_binfmt *new)
 EXPORT_SYMBOL(set_binfmt);
 
 /*
- * set_dumpable stores three-value SUID_DUMP_* into mm->flags.
+ * set_dumpable stores three-value TASK_DUMPABLE_* into mm->flags.
  */
 void set_dumpable(struct mm_struct *mm, int value)
 {
-       if (WARN_ON((unsigned)value > SUID_DUMP_ROOT))
+       if (WARN_ON((unsigned)value > TASK_DUMPABLE_ROOT))
                return;
 
        __mm_flags_set_mask_dumpable(mm, value);
index 1cce4f34a05128ba7f27bfd217db40c1e14da9a6..9cd12f2f004c224aa48f7e6de8ec9b6b54e56ae0 100644 (file)
@@ -341,11 +341,11 @@ static inline bool pid_in_current_pidns(const struct pid *pid)
 static __u32 pidfs_coredump_mask(unsigned long mm_flags)
 {
        switch (__get_dumpable(mm_flags)) {
-       case SUID_DUMP_USER:
+       case TASK_DUMPABLE_OWNER:
                return PIDFD_COREDUMP_USER;
-       case SUID_DUMP_ROOT:
+       case TASK_DUMPABLE_ROOT:
                return PIDFD_COREDUMP_ROOT;
-       case SUID_DUMP_DISABLE:
+       case TASK_DUMPABLE_OFF:
                return PIDFD_COREDUMP_SKIP;
        default:
                WARN_ON_ONCE(true);
index d9acfa89c894bd1608580331e1d5b3018c59123b..da0b316befb81fecbe62a8721f6f71b0c280f33b 100644 (file)
@@ -1909,7 +1909,7 @@ void task_dump_owner(struct task_struct *task, umode_t mode,
                mm = task->mm;
                /* Make non-dumpable tasks owned by some root */
                if (mm) {
-                       if (get_dumpable(mm) != SUID_DUMP_USER) {
+                       if (get_dumpable(mm) != TASK_DUMPABLE_OWNER) {
                                struct user_namespace *user_ns = mm->user_ns;
 
                                uid = make_kuid(user_ns, 0);
index a308e2c23b829fb7eb9032d9a32c7d71c895021b..51ea37b2a0aabf82773afcb1fd41bf37a4e62a43 100644 (file)
@@ -1908,7 +1908,7 @@ enum {
 
 /*
  * The first two bits represent core dump modes for set-user-ID,
- * the modes are SUID_DUMP_* defined in linux/sched/coredump.h
+ * the modes are TASK_DUMPABLE_* defined in linux/sched/coredump.h
  */
 #define MMF_DUMPABLE_BITS 2
 #define MMF_DUMPABLE_MASK (BIT(MMF_DUMPABLE_BITS) - 1)
index 624fda17a78573d5994ca84444206d4b8433588a..ed6547692b6176e565fa308905ef8c6b0e0ff0e2 100644 (file)
@@ -4,9 +4,16 @@
 
 #include <linux/mm_types.h>
 
-#define SUID_DUMP_DISABLE      0       /* No setuid dumping */
-#define SUID_DUMP_USER         1       /* Dump as user of process */
-#define SUID_DUMP_ROOT         2       /* Dump as root */
+/*
+ * Task dumpability mode.  Gates core dump production and ptrace_attach()
+ * authorization.  The numeric values are stable ABI (suid_dumpable
+ * sysctl, prctl(PR_SET_DUMPABLE)); do not renumber.
+ */
+enum task_dumpable {
+       TASK_DUMPABLE_OFF       = 0,    /* no dump; ptrace needs CAP_SYS_PTRACE */
+       TASK_DUMPABLE_OWNER     = 1,    /* default; dump and ptrace by uid match */
+       TASK_DUMPABLE_ROOT      = 2,    /* dump as root; ptrace needs CAP_SYS_PTRACE */
+};
 
 static inline unsigned long __mm_flags_get_dumpable(const struct mm_struct *mm)
 {
@@ -26,7 +33,7 @@ extern void set_dumpable(struct mm_struct *mm, int value);
 /*
  * This returns the actual value of the suid_dumpable flag. For things
  * that are using this for checking for privilege transitions, it must
- * test against SUID_DUMP_USER rather than treating it as a boolean
+ * test against TASK_DUMPABLE_OWNER rather than treating it as a boolean
  * value.
  */
 static inline int __get_dumpable(unsigned long mm_flags)
index f50d73c272d6ee8953f79e4157a74e278a2beff5..507eda655e8d7740dda7a97754dd96dee4d58ea7 100644 (file)
@@ -571,7 +571,7 @@ static void exit_mm(void)
         */
        smp_mb__after_spinlock();
        local_irq_disable();
-       current->user_dumpable = (get_dumpable(mm) == SUID_DUMP_USER);
+       current->user_dumpable = (get_dumpable(mm) == TASK_DUMPABLE_OWNER);
        current->mm = NULL;
        membarrier_update_current_mm(NULL);
        enter_lazy_tlb(mm, current);
index 130043bfc2091c12ccb0a90957baed75e9803735..07398c9c8fe30161041dfaec345de3edc381515d 100644 (file)
@@ -53,7 +53,7 @@ int ptrace_access_vm(struct task_struct *tsk, unsigned long addr,
 
        if (!tsk->ptrace ||
            (current != tsk->parent) ||
-           ((get_dumpable(mm) != SUID_DUMP_USER) &&
+           ((get_dumpable(mm) != TASK_DUMPABLE_OWNER) &&
             !ptracer_capable(tsk, mm->user_ns))) {
                mmput(mm);
                return 0;
@@ -276,7 +276,7 @@ static bool task_still_dumpable(struct task_struct *task, unsigned int mode)
 {
        struct mm_struct *mm = task->mm;
        if (mm) {
-               if (get_dumpable(mm) == SUID_DUMP_USER)
+               if (get_dumpable(mm) == TASK_DUMPABLE_OWNER)
                        return true;
                return ptrace_has_cap(mm->user_ns, mode);
        }
index 62e842055cc9c797d149d36095d5fe720ad03aa8..f1189f719db5aadfce9615ae088023aab608f8fc 100644 (file)
@@ -2568,7 +2568,7 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3,
                error = get_dumpable(me->mm);
                break;
        case PR_SET_DUMPABLE:
-               if (arg2 != SUID_DUMP_DISABLE && arg2 != SUID_DUMP_USER) {
+               if (arg2 != TASK_DUMPABLE_OFF && arg2 != TASK_DUMPABLE_OWNER) {
                        error = -EINVAL;
                        break;
                }