History

sched/coredump: introduce enum task_dumpable

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.

Christian Brauner (Amutable) committed 5 months ago

Commit 4f365e71 parent 5200f5f10 files · +27 −20Browse files

Unified · Split

10 files
  1. arch/arm64/kernel/mte.c +1 −1
  2. fs/coredump.c +2 −2
  3. fs/exec.c +4 −4
  4. fs/pidfs.c +3 −3
  5. fs/proc/base.c +1 −1
  6. include/linux/mm_types.h +1 −1
  7. include/linux/sched/coredump.h +11 −4
  8. kernel/exit.c +1 −1
  9. kernel/ptrace.c +2 −2
  10. kernel/sys.c +1 −1
arch/arm64/kernel/mte.c+1−1
@@ -538,7 +538,7 @@ static int access_remote_tags(struct task_struct *tsk, unsigned long addr, · 537 unmodified lines
538538 return -EPERM;
539539
540540 if (!tsk->ptrace || (current != tsk->parent) ||
541− ((get_dumpable(mm) != SUID_DUMP_USER) &&
541+ ((get_dumpable(mm) != TASK_DUMPABLE_OWNER) &&
542542 !ptracer_capable(tsk, mm->user_ns))) {
543543 mmput(mm);
544544 return -EPERM;
fs/coredump.c+2−2
@@ -873,7 +873,7 @@ static inline bool coredump_socket(struct core_name *cn, struct coredump_params · 872 unmodified lines
873873 static inline bool coredump_force_suid_safe(const struct coredump_params *cprm)
874874 {
875875 /* 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;
877877 }
878878
879879 static bool coredump_file(struct core_name *cn, struct coredump_params *cprm,
@@ -1419,7 +1419,7 @@ EXPORT_SYMBOL(dump_align); · 539 unmodified lines
14191419
14201420 void validate_coredump_safety(void)
14211421 {
1422− if (suid_dumpable == SUID_DUMP_ROOT &&
1422+ if (suid_dumpable == TASK_DUMPABLE_ROOT &&
14231423 core_pattern[0] != '/' && core_pattern[0] != '|' && core_pattern[0] != '@') {
14241424
14251425 coredump_report_failure("Unsafe core_pattern used with fs.suid_dumpable=2: "
fs/exec.c+4−4
@@ -1212,7 +1212,7 @@ int begin_new_exec(struct linux_binprm * bprm) · 1211 unmodified lines
12121212 gid_eq(current_egid(), current_gid())))
12131213 set_dumpable(current->mm, suid_dumpable);
12141214 else
1215− set_dumpable(current->mm, SUID_DUMP_USER);
1215+ set_dumpable(current->mm, TASK_DUMPABLE_OWNER);
12161216
12171217 perf_event_exec();
12181218
@@ -1261,7 +1261,7 @@ int begin_new_exec(struct linux_binprm * bprm) · 42 unmodified lines
12611261 * wait until new credentials are committed
12621262 * by commit_creds() above
12631263 */
1264− if (get_dumpable(me->mm) != SUID_DUMP_USER)
1264+ if (get_dumpable(me->mm) != TASK_DUMPABLE_OWNER)
12651265 perf_event_exit_task(me);
12661266 /*
12671267 * 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
19061906 EXPORT_SYMBOL(set_binfmt);
19071907
19081908 /*
1909− * set_dumpable stores three-value SUID_DUMP_* into mm->flags.
1909+ * set_dumpable stores three-value TASK_DUMPABLE_* into mm->flags.
19101910 */
19111911 void set_dumpable(struct mm_struct *mm, int value)
19121912 {
1913− if (WARN_ON((unsigned)value > SUID_DUMP_ROOT))
1913+ if (WARN_ON((unsigned)value > TASK_DUMPABLE_ROOT))
19141914 return;
19151915
19161916 __mm_flags_set_mask_dumpable(mm, value);
fs/pidfs.c+3−3
@@ -341,11 +341,11 @@ static inline bool pid_in_current_pidns(const struct pid *pid) · 340 unmodified lines
341341 static __u32 pidfs_coredump_mask(unsigned long mm_flags)
342342 {
343343 switch (__get_dumpable(mm_flags)) {
344− case SUID_DUMP_USER:
344+ case TASK_DUMPABLE_OWNER:
345345 return PIDFD_COREDUMP_USER;
346− case SUID_DUMP_ROOT:
346+ case TASK_DUMPABLE_ROOT:
347347 return PIDFD_COREDUMP_ROOT;
348− case SUID_DUMP_DISABLE:
348+ case TASK_DUMPABLE_OFF:
349349 return PIDFD_COREDUMP_SKIP;
350350 default:
351351 WARN_ON_ONCE(true);
fs/proc/base.c+1−1
@@ -1909,7 +1909,7 @@ void task_dump_owner(struct task_struct *task, umode_t mode, · 1908 unmodified lines
19091909 mm = task->mm;
19101910 /* Make non-dumpable tasks owned by some root */
19111911 if (mm) {
1912− if (get_dumpable(mm) != SUID_DUMP_USER) {
1912+ if (get_dumpable(mm) != TASK_DUMPABLE_OWNER) {
19131913 struct user_namespace *user_ns = mm->user_ns;
19141914
19151915 uid = make_kuid(user_ns, 0);
include/linux/mm_types.h+1−1
@@ -1908,7 +1908,7 @@ enum { · 1907 unmodified lines
19081908
19091909 /*
19101910 * 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
19121912 */
19131913 #define MMF_DUMPABLE_BITS 2
19141914 #define MMF_DUMPABLE_MASK (BIT(MMF_DUMPABLE_BITS) - 1)
include/linux/sched/coredump.h+11−4
@@ -4,9 +4,16 @@ · 3 unmodified lines
44
55 #include <linux/mm_types.h>
66
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+};
1017
1118 static inline unsigned long __mm_flags_get_dumpable(const struct mm_struct *mm)
1219 {
@@ -26,7 +33,7 @@ extern void set_dumpable(struct mm_struct *mm, int value); · 13 unmodified lines
2633 /*
2734 * This returns the actual value of the suid_dumpable flag. For things
2835 * 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
3037 * value.
3138 */
3239 static inline int __get_dumpable(unsigned long mm_flags)
kernel/exit.c+1−1
@@ -571,7 +571,7 @@ static void exit_mm(void) · 570 unmodified lines
571571 */
572572 smp_mb__after_spinlock();
573573 local_irq_disable();
574− current->user_dumpable = (get_dumpable(mm) == SUID_DUMP_USER);
574+ current->user_dumpable = (get_dumpable(mm) == TASK_DUMPABLE_OWNER);
575575 current->mm = NULL;
576576 membarrier_update_current_mm(NULL);
577577 enter_lazy_tlb(mm, current);
kernel/ptrace.c+2−2
@@ -53,7 +53,7 @@ int ptrace_access_vm(struct task_struct *tsk, unsigned long addr, · 52 unmodified lines
5353
5454 if (!tsk->ptrace ||
5555 (current != tsk->parent) ||
56− ((get_dumpable(mm) != SUID_DUMP_USER) &&
56+ ((get_dumpable(mm) != TASK_DUMPABLE_OWNER) &&
5757 !ptracer_capable(tsk, mm->user_ns))) {
5858 mmput(mm);
5959 return 0;
@@ -276,7 +276,7 @@ static bool task_still_dumpable(struct task_struct *task, unsigned int mode) · 216 unmodified lines
276276 {
277277 struct mm_struct *mm = task->mm;
278278 if (mm) {
279− if (get_dumpable(mm) == SUID_DUMP_USER)
279+ if (get_dumpable(mm) == TASK_DUMPABLE_OWNER)
280280 return true;
281281 return ptrace_has_cap(mm->user_ns, mode);
282282 }
kernel/sys.c+1−1
@@ -2568,7 +2568,7 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3, · 2567 unmodified lines
25682568 error = get_dumpable(me->mm);
25692569 break;
25702570 case PR_SET_DUMPABLE:
2571− if (arg2 != SUID_DUMP_DISABLE && arg2 != SUID_DUMP_USER) {
2571+ if (arg2 != TASK_DUMPABLE_OFF && arg2 != TASK_DUMPABLE_OWNER) {
25722572 error = -EINVAL;
25732573 break;
25742574 }