From c8b74ac5cf508c7bcec92d197880043af1d2bad7 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 9 Oct 2018 22:23:41 +0200 Subject: [PATCH] logind: validate /run/user/1000 before we set it Let's be safe than sorry, in particular as logind doesn't set it up anymore, but user-runtime-dir@.service does, and logind doesn't really track success of that. (cherry picked from commit b92171124819305985ed292cc472f6668a027425) Related: #1642460 --- src/login/pam_systemd.c | 48 +++++++++++++++++++++++++++++++++++------ 1 file changed, 41 insertions(+), 7 deletions(-) diff --git a/src/login/pam_systemd.c b/src/login/pam_systemd.c index b2b62540bb..64e1b4d1bf 100644 --- a/src/login/pam_systemd.c +++ b/src/login/pam_systemd.c @@ -319,6 +319,36 @@ static int update_environment(pam_handle_t *handle, const char *key, const char return r; } +static bool validate_runtime_directory(pam_handle_t *handle, const char *path, uid_t uid) { + struct stat st; + + assert(path); + + /* Just some extra paranoia: let's not set $XDG_RUNTIME_DIR if the directory we'd set it to isn't actually set + * up properly for us. */ + + if (lstat(path, &st) < 0) { + pam_syslog(handle, LOG_ERR, "Failed to stat() runtime directory '%s': %s", path, strerror(errno)); + goto fail; + } + + if (!S_ISDIR(st.st_mode)) { + pam_syslog(handle, LOG_ERR, "Runtime directory '%s' is not actually a directory.", path); + goto fail; + } + + if (st.st_uid != uid) { + pam_syslog(handle, LOG_ERR, "Runtime directory '%s' is not owned by UID " UID_FMT ", as it should.", path, uid); + goto fail; + } + + return true; + +fail: + pam_syslog(handle, LOG_WARNING, "Not setting $XDG_RUNTIME_DIR, as the directory is not in order."); + return false; +} + _public_ PAM_EXTERN int pam_sm_open_session( pam_handle_t *handle, int flags, @@ -377,10 +407,12 @@ _public_ PAM_EXTERN int pam_sm_open_session( if (asprintf(&rt, "/run/user/"UID_FMT, pw->pw_uid) < 0) return PAM_BUF_ERR; - r = pam_misc_setenv(handle, "XDG_RUNTIME_DIR", rt, 0); - if (r != PAM_SUCCESS) { - pam_syslog(handle, LOG_ERR, "Failed to set runtime dir."); - return r; + if (validate_runtime_directory(handle, rt, pw->pw_uid)) { + r = pam_misc_setenv(handle, "XDG_RUNTIME_DIR", rt, 0); + if (r != PAM_SUCCESS) { + pam_syslog(handle, LOG_ERR, "Failed to set runtime dir."); + return r; + } } r = export_legacy_dbus_address(handle, pw->pw_uid, rt); @@ -584,9 +616,11 @@ _public_ PAM_EXTERN int pam_sm_open_session( * in privileged apps clobbering the runtime directory * unnecessarily. */ - r = update_environment(handle, "XDG_RUNTIME_DIR", runtime_path); - if (r != PAM_SUCCESS) - return r; + if (validate_runtime_directory(handle, runtime_path, pw->pw_uid)) { + r = update_environment(handle, "XDG_RUNTIME_DIR", runtime_path); + if (r != PAM_SUCCESS) + return r; + } r = export_legacy_dbus_address(handle, pw->pw_uid, runtime_path); if (r != PAM_SUCCESS)