WIP: only remove non-dumpable in the non-suid program

From: Willy Tarreau
Date: Sun Dec 26 2021 - 09:17:08 EST


this way sudo doesn't drop its own not-dumpable flag before executing.
---
fs/coredump.c | 2 ++
include/linux/sched/coredump.h | 4 ++--
kernel/sys.c | 15 ++++++++++-----
3 files changed, 14 insertions(+), 7 deletions(-)

diff --git a/fs/coredump.c b/fs/coredump.c
index 3224dee44d30..5f0bfe2c00a6 100644
--- a/fs/coredump.c
+++ b/fs/coredump.c
@@ -609,6 +609,8 @@ void do_coredump(const kernel_siginfo_t *siginfo)
goto fail;
if (!__get_dumpable(cprm.mm_flags))
goto fail;
+ if (cprm.mm_flags & MMF_NOT_DUMPABLE_MASK)
+ goto fail;

cred = prepare_creds();
if (!cred)
diff --git a/include/linux/sched/coredump.h b/include/linux/sched/coredump.h
index 302f31247c90..662508d139e1 100644
--- a/include/linux/sched/coredump.h
+++ b/include/linux/sched/coredump.h
@@ -80,8 +80,8 @@ extern void set_dumpable(struct mm_struct *mm, int value);
*/
static inline int __get_dumpable(unsigned long mm_flags)
{
- if (mm_flags & MMF_NOT_DUMPABLE_MASK)
- return SUID_DUMP_DISABLE;
+ //if (mm_flags & MMF_NOT_DUMPABLE_MASK)
+ // return SUID_DUMP_DISABLE;
return mm_flags & MMF_DUMPABLE_MASK;
}

diff --git a/kernel/sys.c b/kernel/sys.c
index f4405e004145..0ecdb4cc64e7 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -564,7 +564,8 @@ long __sys_setreuid(uid_t ruid, uid_t euid)
goto error;

/* attempt to change ID drops the not-dumpable protection */
- clear_bit(MMF_NOT_DUMPABLE, &current->mm->flags);
+ if (get_dumpable(current->mm))
+ clear_bit(MMF_NOT_DUMPABLE, &current->mm->flags);

return commit_creds(new);

@@ -629,7 +630,8 @@ long __sys_setuid(uid_t uid)
goto error;

/* attempt to change ID drops the not-dumpable protection */
- clear_bit(MMF_NOT_DUMPABLE, &current->mm->flags);
+ if (get_dumpable(current->mm))
+ clear_bit(MMF_NOT_DUMPABLE, &current->mm->flags);

return commit_creds(new);

@@ -711,7 +713,8 @@ long __sys_setresuid(uid_t ruid, uid_t euid, uid_t suid)
goto error;

/* attempt to change ID drops the not-dumpable protection */
- clear_bit(MMF_NOT_DUMPABLE, &current->mm->flags);
+ if (get_dumpable(current->mm))
+ clear_bit(MMF_NOT_DUMPABLE, &current->mm->flags);

return commit_creds(new);

@@ -1225,7 +1228,8 @@ int ksys_setsid(void)
write_unlock_irq(&tasklist_lock);
if (err > 0) {
/* session leaders reset the not-dumpable protection */
- clear_bit(MMF_NOT_DUMPABLE, &current->mm->flags);
+ if (get_dumpable(current->mm))
+ clear_bit(MMF_NOT_DUMPABLE, &current->mm->flags);

proc_sid_connector(group_leader);
sched_autogroup_create_attach(group_leader);
@@ -1627,7 +1631,8 @@ int do_prlimit(struct task_struct *tsk, unsigned int resource,
* If an application wants to change its own core dump settings, it
* wants to decide on its dumpability so we reset MMF_NOT_DUMPABLE.
*/
- if (!retval && new_rlim && resource == RLIMIT_CORE && tsk == current)
+ if (!retval && new_rlim && resource == RLIMIT_CORE && tsk == current &&
+ get_dumpable(tsk->mm))
clear_bit(MMF_NOT_DUMPABLE, &tsk->mm->flags);
out:
read_unlock(&tasklist_lock);
--
2.17.5


--qMm9M+Fa2AknHoGS
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="0002-WIP-only-change-not_dumpable-via-prctl-and-setrlimit.patch"