Files
tmux/compat/keyring-linux.c
Ilya Priven bba451c959 Give the server its own session keyring on Linux
The server otherwise keeps the session keyring of the login session that
started it, which pam_keyinit(8) may revoke when that session ends,
leaving the server and its panes unable to use the kernel keyring. Join
a new session keyring with the user keyring linked in once the
configuration file has been loaded, and revoke it when the server exits.

This is controlled by a new session-keyring server option, on by
default.
2026-10-12 11:26:28 +00:00

43 lines
1.0 KiB
C

#include <sys/types.h>
#include <sys/syscall.h>
#include <linux/keyctl.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include "tmux.h"
/* Serial of the session keyring we joined, or 0 if none. */
static long keyring_serial;
/*
* Create a new session keyring since the current one belongs to the login
* session which we're meant to outlive (and pam_keyinit(8) is likely to revoke
* the login session's keyring when it ends).
*/
void
keyring_join(void)
{
long serial;
serial = syscall(SYS_keyctl, KEYCTL_JOIN_SESSION_KEYRING, NULL);
if (serial == -1) {
log_debug("%s: join failed: %s", __func__, strerror(errno));
return;
}
if (syscall(SYS_keyctl, KEYCTL_LINK, KEY_SPEC_USER_KEYRING,
KEY_SPEC_SESSION_KEYRING) == -1)
log_debug("%s: link failed: %s", __func__, strerror(errno));
keyring_serial = serial;
}
void
keyring_revoke(void)
{
if (keyring_serial == 0)
return;
if (syscall(SYS_keyctl, KEYCTL_REVOKE, keyring_serial) == -1)
log_debug("%s: revoke failed: %s", __func__, strerror(errno));
}