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