Patch-Source: https://github.com/jjk-jacky/pam_rundir/commit/5ae2ee1a3411e973ebe56421850b7e08c23d6319 Patch-Source: https://github.com/jjk-jacky/pam_rundir/commit/4782a657d52cce68a029d461446d898ce9cdb50d From 5ae2ee1a3411e973ebe56421850b7e08c23d6319 Mon Sep 17 00:00:00 2001 From: Olivier Brunel Date: Sun, 15 Apr 2018 15:46:24 +0200 Subject: [PATCH] Use prctl to bypass permission checks on mkdir... In case the parent dir (e.g. /run/user) isn't group writable, this will allow mkdir to still succeed. Thanks to Daniel Santana. --- pam_rundir.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/pam_rundir.c b/pam_rundir.c index 2d2c201..51082b7 100644 --- a/pam_rundir.c +++ b/pam_rundir.c @@ -24,6 +24,8 @@ #include #include #include +#include +#include #include #include #include @@ -396,6 +398,9 @@ pam_sm_open_session (pam_handle_t *pamh, int flags, int argc, const char **argv) goto done; } + /* to bypass permission checks for mkdir, in case it isn't group + * writable */ + prctl (PR_SET_SECUREBITS, SECBIT_NO_SETUID_FIXUP); /* set euid so if we do create the dir, it is own by the user */ if (seteuid (pw->pw_uid) < 0) { -- From 4782a657d52cce68a029d461446d898ce9cdb50d Mon Sep 17 00:00:00 2001 From: Olivier Brunel Date: Mon, 12 Nov 2018 09:15:50 +0100 Subject: [PATCH] Fix security issue introduced in previous commit Setting SECBIT_NO_SETUID_FIXUP to bypass permission checks on mkdir is fine, so long as we reset it afterwards. Else it would "leak" and could cause security issue. Thanks to Antek Pilat. --- pam_rundir.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/pam_rundir.c b/pam_rundir.c index 51082b7..5cafdcf 100644 --- a/pam_rundir.c +++ b/pam_rundir.c @@ -362,6 +362,7 @@ pam_sm_open_session (pam_handle_t *pamh, int flags, int argc, const char **argv) char file[sizeof (PARENT_DIR) + l + 2]; int fd; int count = 0; + int secbits = -1; print_filename (file, (int) pw->pw_uid, l); fd = open_and_lock (file); @@ -400,7 +401,9 @@ pam_sm_open_session (pam_handle_t *pamh, int flags, int argc, const char **argv) /* to bypass permission checks for mkdir, in case it isn't group * writable */ - prctl (PR_SET_SECUREBITS, SECBIT_NO_SETUID_FIXUP); + secbits = prctl (PR_GET_SECUREBITS); + if (secbits != -1) + prctl (PR_SET_SECUREBITS, (unsigned long) secbits | SECBIT_NO_SETUID_FIXUP); /* set euid so if we do create the dir, it is own by the user */ if (seteuid (pw->pw_uid) < 0) { @@ -426,6 +429,8 @@ pam_sm_open_session (pam_handle_t *pamh, int flags, int argc, const char **argv) } done: + if (secbits != -1) + prctl (PR_SET_SECUREBITS, (unsigned long) secbits); close (fd); /* also unlocks */ }