From 2c4f7bac002c552645b022049caad047c02f69bc Mon Sep 17 00:00:00 2001 From: jca Date: Fri, 14 Nov 2025 10:08:10 +0000 Subject: [PATCH] Implement XDG_RUNTIME_DIR support through setusercontext(LOGIN_SETXDGENV) If LOGIN_SETXDGENV is passed in the flags, ensure the presence and usability of a runtime directory dedicated to . Set the XDG_RUNTIME_DIR variable only if the directory is usable. With feedback from deraadt@, matthieu@ and guenther@. ok deraadt@ robert@ --- etc/daily | 4 +-- etc/rc | 5 ++- include/login_cap.h | 5 +-- lib/libc/gen/login_cap.c | 68 +++++++++++++++++++++++++++++++++++++++- 4 files changed, 76 insertions(+), 6 deletions(-) diff --git a/etc/daily b/etc/daily index 96e486875a5..a5f991347b5 100644 --- a/etc/daily +++ b/etc/daily @@ -1,5 +1,5 @@ # -# $OpenBSD: daily,v 1.101 2025/03/31 17:35:28 schwarze Exp $ +# $OpenBSD: daily,v 1.102 2025/11/14 10:08:10 jca Exp $ # From: @(#)daily 8.2 (Berkeley) 1/25/94 # # For local additions, create the file /etc/daily.local. @@ -52,7 +52,7 @@ if [ -d /tmp -a ! -L /tmp ]; then -o -path './tmux-*' \) -prune -o \ -type f -and ! -path './*.s[eh]m' -atime +7 -delete 2>/dev/null find -x . -type d -mtime +1 ! -path ./vi.recover ! -path ./.X11-unix \ - ! -path ./.ICE-unix ! -name . \ + ! -path ./.ICE-unix ! -path ./run/user ! -name . \ -delete >/dev/null 2>&1; } fi diff --git a/etc/rc b/etc/rc index ece0104c483..53ceedd7133 100644 --- a/etc/rc +++ b/etc/rc @@ -1,4 +1,4 @@ -# $OpenBSD: rc,v 1.587 2025/10/21 15:55:35 deraadt Exp $ +# $OpenBSD: rc,v 1.588 2025/11/14 10:08:10 jca Exp $ # System startup script run by init on autoboot or after single-user. # Output and error are redirected to console by init, and the console is the @@ -610,6 +610,9 @@ echo clearing /tmp # correct permissions. [[ -d /usr/X11R6/lib ]] && mkdir -m 1777 /tmp/.{X11,ICE}-unix +# Create parent directory for XDG_RUNTIME_DIR +mkdir -p -m 755 /tmp/run/user + [[ -f /etc/rc.securelevel ]] && sh /etc/rc.securelevel # rc.securelevel did not specifically set -1 or 2, so select the default: 1. diff --git a/include/login_cap.h b/include/login_cap.h index 7c8cc19b98b..76b050084dd 100644 --- a/include/login_cap.h +++ b/include/login_cap.h @@ -1,4 +1,4 @@ -/* $OpenBSD: login_cap.h,v 1.19 2022/03/01 01:22:11 tedu Exp $ */ +/* $OpenBSD: login_cap.h,v 1.20 2025/11/14 10:08:10 jca Exp $ */ /*- * Copyright (c) 1995,1997 Berkeley Software Design, Inc. All rights reserved. @@ -55,7 +55,8 @@ #define LOGIN_SETUSER 0x0040 /* Set user */ #define LOGIN_SETENV 0x0080 /* Set environment */ #define LOGIN_SETRTABLE 0x0100 /* Set rtable */ -#define LOGIN_SETALL 0x01ff /* Set all. */ +#define LOGIN_SETXDGENV 0x0200 /* Set XDG environment variables */ +#define LOGIN_SETALL 0x03ff /* Set all. */ #define BI_AUTH "authorize" /* Accepted authentication */ #define BI_REJECT "reject" /* Rejected authentication */ diff --git a/lib/libc/gen/login_cap.c b/lib/libc/gen/login_cap.c index 1460181b376..8b93af3748c 100644 --- a/lib/libc/gen/login_cap.c +++ b/lib/libc/gen/login_cap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: login_cap.c,v 1.46 2022/12/27 17:10:06 jmc Exp $ */ +/* $OpenBSD: login_cap.c,v 1.47 2025/11/14 10:08:10 jca Exp $ */ /* * Copyright (c) 2000-2004 Todd C. Miller @@ -566,6 +566,64 @@ gsetrl(login_cap_t *lc, int what, char *name, int type) return (0); } +/* + * Setup XDG_RUNTIME_DIR unless we encounter an error. Inability to + * create the directory is not a fatal error. + */ +static int +setxdgenv(uid_t uid, struct passwd *pwd) +{ + char rundir[PATH_MAX]; + struct stat sb; + int fd = -1; + int flags; + int ret = 0; + + snprintf(rundir, sizeof(rundir), "/tmp/run/user/%u", uid); + + if (mkdir(rundir, S_IRUSR|S_IWUSR|S_IXUSR) == -1 && errno != EEXIST) { + syslog(LOG_ERR, "could not create %s: %m", rundir); + goto cleanup; + } + + fd = open(rundir, O_RDONLY|O_DIRECTORY|O_NOFOLLOW|O_CLOEXEC|O_CLOFORK); + if (fd == -1) { + syslog(LOG_ERR, "could not open %s: %m", rundir); + goto cleanup; + } + if (fstat(fd, &sb) == -1) { + syslog(LOG_ERR, "could not stat %s: %m", rundir); + goto cleanup; + } + if ((sb.st_mode & ALLPERMS) != (S_IRUSR|S_IWUSR|S_IXUSR)) { + syslog(LOG_ERR, "WARNING: wrong permissions %o on %s, " + "ignoring", (sb.st_mode & ALLPERMS), rundir); + goto cleanup; + } + if (sb.st_uid == 0 && sb.st_gid == 0) { + if (fchown(fd, uid, pwd->pw_gid) == -1) { + syslog(LOG_ERR, "could not chown %s: %m", rundir); + goto cleanup; + } + } else if (sb.st_uid != uid || sb.st_gid != pwd->pw_gid) { + syslog(LOG_ERR, "WARNING: wrong ownership " + "%u:%u on %s, ignoring", + sb.st_uid, sb.st_gid, rundir); + goto cleanup; + } + + if (login_setenv("XDG_RUNTIME_DIR", rundir, pwd, 0) != 0) { + syslog(LOG_ERR, "could not set XDG_RUNTIME_DIR: %m"); + ret = -1; + } + +cleanup: + if (fd != -1) + close(fd); + + return ret; +} + int setclasscontext(char *class, u_int flags) { @@ -667,6 +725,14 @@ setusercontext(login_cap_t *lc, struct passwd *pwd, uid_t uid, u_int flags) return (-1); } + if ((flags & LOGIN_SETXDGENV) && !login_getcapbool(lc, "noxdg", 0)) { + if (setxdgenv(uid, pwd) == -1) { + /* Error logged in setxdgenv(). */ + login_close(lc); + return (-1); + } + } + if (flags & LOGIN_SETUSER) { if (setresuid(uid, uid, uid) == -1) { syslog(LOG_ERR, "setresuid(%u,%u,%u): %m",