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.
Unified · Split
| @@ -538,7 +538,7 @@ static int access_remote_tags(struct task_struct *tsk, unsigned long addr, · 537 unmodified lines | ||
| 538 | 538 | return -EPERM; |
| 539 | 539 | |
| 540 | 540 | if (!tsk->ptrace || (current != tsk->parent) || |
| 541 | − ((get_dumpable(mm) != SUID_DUMP_USER) && | |
| 541 | + ((get_dumpable(mm) != TASK_DUMPABLE_OWNER) && | |
| 542 | 542 | !ptracer_capable(tsk, mm->user_ns))) { |
| 543 | 543 | mmput(mm); |
| 544 | 544 | return -EPERM; |
| @@ -873,7 +873,7 @@ static inline bool coredump_socket(struct core_name *cn, struct coredump_params · 872 unmodified lines | ||
| 873 | 873 | static inline bool coredump_force_suid_safe(const struct coredump_params *cprm) |
| 874 | 874 | { |
| 875 | 875 | /* Require nonrelative corefile path and be extra careful. */ |
| 876 | − return __get_dumpable(cprm->mm_flags) == SUID_DUMP_ROOT; | |
| 876 | + return __get_dumpable(cprm->mm_flags) == TASK_DUMPABLE_ROOT; | |
| 877 | 877 | } |
| 878 | 878 | |
| 879 | 879 | static bool coredump_file(struct core_name *cn, struct coredump_params *cprm, |
| @@ -1419,7 +1419,7 @@ EXPORT_SYMBOL(dump_align); · 539 unmodified lines | ||
| 1419 | 1419 | |
| 1420 | 1420 | void validate_coredump_safety(void) |
| 1421 | 1421 | { |
| 1422 | − if (suid_dumpable == SUID_DUMP_ROOT && | |
| 1422 | + if (suid_dumpable == TASK_DUMPABLE_ROOT && | |
| 1423 | 1423 | core_pattern[0] != '/' && core_pattern[0] != '|' && core_pattern[0] != '@') { |
| 1424 | 1424 | |
| 1425 | 1425 | coredump_report_failure("Unsafe core_pattern used with fs.suid_dumpable=2: " |
| @@ -1212,7 +1212,7 @@ int begin_new_exec(struct linux_binprm * bprm) · 1211 unmodified lines | ||
| 1212 | 1212 | gid_eq(current_egid(), current_gid()))) |
| 1213 | 1213 | set_dumpable(current->mm, suid_dumpable); |
| 1214 | 1214 | else |
| 1215 | − set_dumpable(current->mm, SUID_DUMP_USER); | |
| 1215 | + set_dumpable(current->mm, TASK_DUMPABLE_OWNER); | |
| 1216 | 1216 | |
| 1217 | 1217 | perf_event_exec(); |
| 1218 | 1218 | |
| @@ -1261,7 +1261,7 @@ int begin_new_exec(struct linux_binprm * bprm) · 42 unmodified lines | ||
| 1261 | 1261 | * wait until new credentials are committed |
| 1262 | 1262 | * by commit_creds() above |
| 1263 | 1263 | */ |
| 1264 | − if (get_dumpable(me->mm) != SUID_DUMP_USER) | |
| 1264 | + if (get_dumpable(me->mm) != TASK_DUMPABLE_OWNER) | |
| 1265 | 1265 | perf_event_exit_task(me); |
| 1266 | 1266 | /* |
| 1267 | 1267 | * cred_guard_mutex must be held at least to this point to prevent |
| @@ -1906,11 +1906,11 @@ void set_binfmt(struct linux_binfmt *new) · 638 unmodified lines | ||
| 1906 | 1906 | EXPORT_SYMBOL(set_binfmt); |
| 1907 | 1907 | |
| 1908 | 1908 | /* |
| 1909 | − * set_dumpable stores three-value SUID_DUMP_* into mm->flags. | |
| 1909 | + * set_dumpable stores three-value TASK_DUMPABLE_* into mm->flags. | |
| 1910 | 1910 | */ |
| 1911 | 1911 | void set_dumpable(struct mm_struct *mm, int value) |
| 1912 | 1912 | { |
| 1913 | − if (WARN_ON((unsigned)value > SUID_DUMP_ROOT)) | |
| 1913 | + if (WARN_ON((unsigned)value > TASK_DUMPABLE_ROOT)) | |
| 1914 | 1914 | return; |
| 1915 | 1915 | |
| 1916 | 1916 | __mm_flags_set_mask_dumpable(mm, value); |
| @@ -341,11 +341,11 @@ static inline bool pid_in_current_pidns(const struct pid *pid) · 340 unmodified lines | ||
| 341 | 341 | static __u32 pidfs_coredump_mask(unsigned long mm_flags) |
| 342 | 342 | { |
| 343 | 343 | switch (__get_dumpable(mm_flags)) { |
| 344 | − case SUID_DUMP_USER: | |
| 344 | + case TASK_DUMPABLE_OWNER: | |
| 345 | 345 | return PIDFD_COREDUMP_USER; |
| 346 | − case SUID_DUMP_ROOT: | |
| 346 | + case TASK_DUMPABLE_ROOT: | |
| 347 | 347 | return PIDFD_COREDUMP_ROOT; |
| 348 | − case SUID_DUMP_DISABLE: | |
| 348 | + case TASK_DUMPABLE_OFF: | |
| 349 | 349 | return PIDFD_COREDUMP_SKIP; |
| 350 | 350 | default: |
| 351 | 351 | WARN_ON_ONCE(true); |
| @@ -1909,7 +1909,7 @@ void task_dump_owner(struct task_struct *task, umode_t mode, · 1908 unmodified lines | ||
| 1909 | 1909 | mm = task->mm; |
| 1910 | 1910 | /* Make non-dumpable tasks owned by some root */ |
| 1911 | 1911 | if (mm) { |
| 1912 | − if (get_dumpable(mm) != SUID_DUMP_USER) { | |
| 1912 | + if (get_dumpable(mm) != TASK_DUMPABLE_OWNER) { | |
| 1913 | 1913 | struct user_namespace *user_ns = mm->user_ns; |
| 1914 | 1914 | |
| 1915 | 1915 | uid = make_kuid(user_ns, 0); |
| @@ -1908,7 +1908,7 @@ enum { · 1907 unmodified lines | ||
| 1908 | 1908 | |
| 1909 | 1909 | /* |
| 1910 | 1910 | * The first two bits represent core dump modes for set-user-ID, |
| 1911 | − * the modes are SUID_DUMP_* defined in linux/sched/coredump.h | |
| 1911 | + * the modes are TASK_DUMPABLE_* defined in linux/sched/coredump.h | |
| 1912 | 1912 | */ |
| 1913 | 1913 | #define MMF_DUMPABLE_BITS 2 |
| 1914 | 1914 | #define MMF_DUMPABLE_MASK (BIT(MMF_DUMPABLE_BITS) - 1) |
| @@ -4,9 +4,16 @@ · 3 unmodified lines | ||
| 4 | 4 | |
| 5 | 5 | #include <linux/mm_types.h> |
| 6 | 6 | |
| 7 | −#define SUID_DUMP_DISABLE 0 /* No setuid dumping */ | |
| 8 | −#define SUID_DUMP_USER 1 /* Dump as user of process */ | |
| 9 | −#define SUID_DUMP_ROOT 2 /* Dump as root */ | |
| 7 | +/* | |
| 8 | + * Task dumpability mode. Gates core dump production and ptrace_attach() | |
| 9 | + * authorization. The numeric values are stable ABI (suid_dumpable | |
| 10 | + * sysctl, prctl(PR_SET_DUMPABLE)); do not renumber. | |
| 11 | + */ | |
| 12 | +enum task_dumpable { | |
| 13 | + TASK_DUMPABLE_OFF = 0, /* no dump; ptrace needs CAP_SYS_PTRACE */ | |
| 14 | + TASK_DUMPABLE_OWNER = 1, /* default; dump and ptrace by uid match */ | |
| 15 | + TASK_DUMPABLE_ROOT = 2, /* dump as root; ptrace needs CAP_SYS_PTRACE */ | |
| 16 | +}; | |
| 10 | 17 | |
| 11 | 18 | static inline unsigned long __mm_flags_get_dumpable(const struct mm_struct *mm) |
| 12 | 19 | { |
| @@ -26,7 +33,7 @@ extern void set_dumpable(struct mm_struct *mm, int value); · 13 unmodified lines | ||
| 26 | 33 | /* |
| 27 | 34 | * This returns the actual value of the suid_dumpable flag. For things |
| 28 | 35 | * that are using this for checking for privilege transitions, it must |
| 29 | − * test against SUID_DUMP_USER rather than treating it as a boolean | |
| 36 | + * test against TASK_DUMPABLE_OWNER rather than treating it as a boolean | |
| 30 | 37 | * value. |
| 31 | 38 | */ |
| 32 | 39 | static inline int __get_dumpable(unsigned long mm_flags) |
| @@ -571,7 +571,7 @@ static void exit_mm(void) · 570 unmodified lines | ||
| 571 | 571 | */ |
| 572 | 572 | smp_mb__after_spinlock(); |
| 573 | 573 | local_irq_disable(); |
| 574 | − current->user_dumpable = (get_dumpable(mm) == SUID_DUMP_USER); | |
| 574 | + current->user_dumpable = (get_dumpable(mm) == TASK_DUMPABLE_OWNER); | |
| 575 | 575 | current->mm = NULL; |
| 576 | 576 | membarrier_update_current_mm(NULL); |
| 577 | 577 | enter_lazy_tlb(mm, current); |
| @@ -53,7 +53,7 @@ int ptrace_access_vm(struct task_struct *tsk, unsigned long addr, · 52 unmodified lines | ||
| 53 | 53 | |
| 54 | 54 | if (!tsk->ptrace || |
| 55 | 55 | (current != tsk->parent) || |
| 56 | − ((get_dumpable(mm) != SUID_DUMP_USER) && | |
| 56 | + ((get_dumpable(mm) != TASK_DUMPABLE_OWNER) && | |
| 57 | 57 | !ptracer_capable(tsk, mm->user_ns))) { |
| 58 | 58 | mmput(mm); |
| 59 | 59 | return 0; |
| @@ -276,7 +276,7 @@ static bool task_still_dumpable(struct task_struct *task, unsigned int mode) · 216 unmodified lines | ||
| 276 | 276 | { |
| 277 | 277 | struct mm_struct *mm = task->mm; |
| 278 | 278 | if (mm) { |
| 279 | − if (get_dumpable(mm) == SUID_DUMP_USER) | |
| 279 | + if (get_dumpable(mm) == TASK_DUMPABLE_OWNER) | |
| 280 | 280 | return true; |
| 281 | 281 | return ptrace_has_cap(mm->user_ns, mode); |
| 282 | 282 | } |
| @@ -2568,7 +2568,7 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3, · 2567 unmodified lines | ||
| 2568 | 2568 | error = get_dumpable(me->mm); |
| 2569 | 2569 | break; |
| 2570 | 2570 | case PR_SET_DUMPABLE: |
| 2571 | − if (arg2 != SUID_DUMP_DISABLE && arg2 != SUID_DUMP_USER) { | |
| 2571 | + if (arg2 != TASK_DUMPABLE_OFF && arg2 != TASK_DUMPABLE_OWNER) { | |
| 2572 | 2572 | error = -EINVAL; |
| 2573 | 2573 | break; |
| 2574 | 2574 | } |