Change the argument to set_dumpable from task->mm to task. This allows us to later add hooks to modify a task's property according to whether it is a non-dumpable task. Non dumpable tasks demand a higher level of security. Changes the dumpable value from in to unsigned int as negative number is not allowed.
Signed-off-by: Tim Chen <tim.c.c...@linux.intel.com> --- fs/exec.c | 14 ++++++++------ include/linux/sched/coredump.h | 2 +- kernel/cred.c | 2 +- kernel/sys.c | 2 +- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/fs/exec.c b/fs/exec.c index 1ebf6e5..e204830 100644 --- a/fs/exec.c +++ b/fs/exec.c @@ -1362,9 +1362,9 @@ void setup_new_exec(struct linux_binprm * bprm) if (bprm->interp_flags & BINPRM_FLAGS_ENFORCE_NONDUMP || !(uid_eq(current_euid(), current_uid()) && gid_eq(current_egid(), current_gid()))) - set_dumpable(current->mm, suid_dumpable); + set_dumpable(current, (unsigned int) suid_dumpable); else - set_dumpable(current->mm, SUID_DUMP_USER); + set_dumpable(current, SUID_DUMP_USER); arch_setup_new_exec(); perf_event_exec(); @@ -1943,17 +1943,19 @@ EXPORT_SYMBOL(set_binfmt); /* * set_dumpable stores three-value SUID_DUMP_* into mm->flags. */ -void set_dumpable(struct mm_struct *mm, int value) +void set_dumpable(struct task_struct *tsk, unsigned int value) { unsigned long old, new; - if (WARN_ON((unsigned)value > SUID_DUMP_ROOT)) + if (WARN_ON(value > SUID_DUMP_ROOT)) + return; + if (WARN_ON(!tsk->mm)) return; do { - old = READ_ONCE(mm->flags); + old = READ_ONCE(tsk->mm->flags); new = (old & ~MMF_DUMPABLE_MASK) | value; - } while (cmpxchg(&mm->flags, old, new) != old); + } while (cmpxchg(&tsk->mm->flags, old, new) != old); } SYSCALL_DEFINE3(execve, diff --git a/include/linux/sched/coredump.h b/include/linux/sched/coredump.h index ec912d0..c02b1ab 100644 --- a/include/linux/sched/coredump.h +++ b/include/linux/sched/coredump.h @@ -14,7 +14,7 @@ #define MMF_DUMPABLE_BITS 2 #define MMF_DUMPABLE_MASK ((1 << MMF_DUMPABLE_BITS) - 1) -extern void set_dumpable(struct mm_struct *mm, int value); +extern void set_dumpable(struct task_struct *tsk, unsigned 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 diff --git a/kernel/cred.c b/kernel/cred.c index ecf0365..18ef774 100644 --- a/kernel/cred.c +++ b/kernel/cred.c @@ -446,7 +446,7 @@ int commit_creds(struct cred *new) !gid_eq(old->fsgid, new->fsgid) || !cred_cap_issubset(old, new)) { if (task->mm) - set_dumpable(task->mm, suid_dumpable); + set_dumpable(task, (unsigned int) suid_dumpable); task->pdeath_signal = 0; smp_wmb(); } diff --git a/kernel/sys.c b/kernel/sys.c index cf5c675..d0892cd 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -2292,7 +2292,7 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3, error = -EINVAL; break; } - set_dumpable(me->mm, arg2); + set_dumpable(me, (unsigned int) arg2); break; case PR_SET_UNALIGN: -- 2.9.4