pam_keyinit: thread-safe implementation
Resolves: #2061696 Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
This commit is contained in:
parent
d0e126a9a6
commit
aba8c1f8a4
150
pam-1.5.1-pam-keyinit-thread-safe.patch
Normal file
150
pam-1.5.1-pam-keyinit-thread-safe.patch
Normal file
@ -0,0 +1,150 @@
|
||||
From a35e092e24ee7632346a0e1b4a203c04d4cd2c62 Mon Sep 17 00:00:00 2001
|
||||
From: Iker Pedrosa <ipedrosa@redhat.com>
|
||||
Date: Mon, 24 Jan 2022 15:43:23 +0100
|
||||
Subject: [PATCH] pam_keyinit: thread-safe implementation
|
||||
|
||||
* modules/pam_keyinit/pam_keyinit.c: Bypass setre*id() C library calls
|
||||
with kernel calls and change global variables definitions to be
|
||||
thread-safe.
|
||||
|
||||
Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1997969
|
||||
Signed-off-by: Iker Pedrosa <ipedrosa@redhat.com>
|
||||
Co-Authored-By: Andreas Schneider <asn@samba.org>
|
||||
---
|
||||
modules/pam_keyinit/pam_keyinit.c | 60 ++++++++++++++++++++++---------
|
||||
1 file changed, 44 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/modules/pam_keyinit/pam_keyinit.c b/modules/pam_keyinit/pam_keyinit.c
|
||||
index 92e4953b..df9804b9 100644
|
||||
--- a/modules/pam_keyinit/pam_keyinit.c
|
||||
+++ b/modules/pam_keyinit/pam_keyinit.c
|
||||
@@ -21,6 +21,7 @@
|
||||
#include <security/pam_modutil.h>
|
||||
#include <security/pam_ext.h>
|
||||
#include <sys/syscall.h>
|
||||
+#include <stdatomic.h>
|
||||
|
||||
#define KEY_SPEC_SESSION_KEYRING -3 /* ID for session keyring */
|
||||
#define KEY_SPEC_USER_KEYRING -4 /* ID for UID-specific keyring */
|
||||
@@ -31,12 +32,12 @@
|
||||
#define KEYCTL_REVOKE 3 /* revoke a key */
|
||||
#define KEYCTL_LINK 8 /* link a key into a keyring */
|
||||
|
||||
-static int my_session_keyring = 0;
|
||||
-static int session_counter = 0;
|
||||
-static int do_revoke = 0;
|
||||
-static uid_t revoke_as_uid;
|
||||
-static gid_t revoke_as_gid;
|
||||
-static int xdebug = 0;
|
||||
+static _Thread_local int my_session_keyring = 0;
|
||||
+static _Atomic int session_counter = 0;
|
||||
+static _Thread_local int do_revoke = 0;
|
||||
+static _Thread_local uid_t revoke_as_uid;
|
||||
+static _Thread_local gid_t revoke_as_gid;
|
||||
+static _Thread_local int xdebug = 0;
|
||||
|
||||
static void debug(pam_handle_t *pamh, const char *fmt, ...)
|
||||
__attribute__((format(printf, 2, 3)));
|
||||
@@ -64,6 +65,33 @@ static void error(pam_handle_t *pamh, const char *fmt, ...)
|
||||
va_end(va);
|
||||
}
|
||||
|
||||
+static int pam_setreuid(uid_t ruid, uid_t euid)
|
||||
+{
|
||||
+#if defined(SYS_setreuid32)
|
||||
+ return syscall(SYS_setreuid32, ruid, euid);
|
||||
+#else
|
||||
+ return syscall(SYS_setreuid, ruid, euid);
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
+static int pam_setregid(gid_t rgid, gid_t egid)
|
||||
+{
|
||||
+#if defined(SYS_setregid32)
|
||||
+ return syscall(SYS_setregid32, rgid, egid);
|
||||
+#else
|
||||
+ return syscall(SYS_setregid, rgid, egid);
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
+static int pam_setresuid(uid_t ruid, uid_t euid, uid_t suid)
|
||||
+{
|
||||
+#if defined(SYS_setresuid32)
|
||||
+ return syscall(SYS_setresuid32, ruid, euid, suid);
|
||||
+#else
|
||||
+ return syscall(SYS_setresuid, ruid, euid, suid);
|
||||
+#endif
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* initialise the session keyring for this process
|
||||
*/
|
||||
@@ -140,14 +168,14 @@ static int kill_keyrings(pam_handle_t *pamh, int error_ret)
|
||||
|
||||
/* switch to the real UID and GID so that we have permission to
|
||||
* revoke the key */
|
||||
- if (revoke_as_gid != old_gid && setregid(-1, revoke_as_gid) < 0) {
|
||||
+ if (revoke_as_gid != old_gid && pam_setregid(-1, revoke_as_gid) < 0) {
|
||||
error(pamh, "Unable to change GID to %d temporarily\n", revoke_as_gid);
|
||||
return error_ret;
|
||||
}
|
||||
|
||||
- if (revoke_as_uid != old_uid && setresuid(-1, revoke_as_uid, old_uid) < 0) {
|
||||
+ if (revoke_as_uid != old_uid && pam_setresuid(-1, revoke_as_uid, old_uid) < 0) {
|
||||
error(pamh, "Unable to change UID to %d temporarily\n", revoke_as_uid);
|
||||
- if (getegid() != old_gid && setregid(-1, old_gid) < 0)
|
||||
+ if (getegid() != old_gid && pam_setregid(-1, old_gid) < 0)
|
||||
error(pamh, "Unable to change GID back to %d\n", old_gid);
|
||||
return error_ret;
|
||||
}
|
||||
@@ -157,12 +185,12 @@ static int kill_keyrings(pam_handle_t *pamh, int error_ret)
|
||||
}
|
||||
|
||||
/* return to the original UID and GID (probably root) */
|
||||
- if (revoke_as_uid != old_uid && setreuid(-1, old_uid) < 0) {
|
||||
+ if (revoke_as_uid != old_uid && pam_setreuid(-1, old_uid) < 0) {
|
||||
error(pamh, "Unable to change UID back to %d\n", old_uid);
|
||||
ret = error_ret;
|
||||
}
|
||||
|
||||
- if (revoke_as_gid != old_gid && setregid(-1, old_gid) < 0) {
|
||||
+ if (revoke_as_gid != old_gid && pam_setregid(-1, old_gid) < 0) {
|
||||
error(pamh, "Unable to change GID back to %d\n", old_gid);
|
||||
ret = error_ret;
|
||||
}
|
||||
@@ -215,14 +243,14 @@ static int do_keyinit(pam_handle_t *pamh, int argc, const char **argv, int error
|
||||
|
||||
/* switch to the real UID and GID so that the keyring ends up owned by
|
||||
* the right user */
|
||||
- if (gid != old_gid && setregid(gid, -1) < 0) {
|
||||
+ if (gid != old_gid && pam_setregid(gid, -1) < 0) {
|
||||
error(pamh, "Unable to change GID to %d temporarily\n", gid);
|
||||
return error_ret;
|
||||
}
|
||||
|
||||
- if (uid != old_uid && setreuid(uid, -1) < 0) {
|
||||
+ if (uid != old_uid && pam_setreuid(uid, -1) < 0) {
|
||||
error(pamh, "Unable to change UID to %d temporarily\n", uid);
|
||||
- if (setregid(old_gid, -1) < 0)
|
||||
+ if (pam_setregid(old_gid, -1) < 0)
|
||||
error(pamh, "Unable to change GID back to %d\n", old_gid);
|
||||
return error_ret;
|
||||
}
|
||||
@@ -230,12 +258,12 @@ static int do_keyinit(pam_handle_t *pamh, int argc, const char **argv, int error
|
||||
ret = init_keyrings(pamh, force, error_ret);
|
||||
|
||||
/* return to the original UID and GID (probably root) */
|
||||
- if (uid != old_uid && setreuid(old_uid, -1) < 0) {
|
||||
+ if (uid != old_uid && pam_setreuid(old_uid, -1) < 0) {
|
||||
error(pamh, "Unable to change UID back to %d\n", old_uid);
|
||||
ret = error_ret;
|
||||
}
|
||||
|
||||
- if (gid != old_gid && setregid(old_gid, -1) < 0) {
|
||||
+ if (gid != old_gid && pam_setregid(old_gid, -1) < 0) {
|
||||
error(pamh, "Unable to change GID back to %d\n", old_gid);
|
||||
ret = error_ret;
|
||||
}
|
||||
--
|
||||
2.35.1
|
||||
|
8
pam.spec
8
pam.spec
@ -3,7 +3,7 @@
|
||||
Summary: An extensible library which provides authentication for applications
|
||||
Name: pam
|
||||
Version: 1.5.1
|
||||
Release: 9%{?dist}
|
||||
Release: 10%{?dist}
|
||||
# The library is BSD licensed with option to relicense as GPLv2+
|
||||
# - this option is redundant as the BSD license allows that anyway.
|
||||
# pam_timestamp, pam_loginuid, and pam_console modules are GPLv2+.
|
||||
@ -32,6 +32,8 @@ Patch4: pam-1.5.1-timestamp-openssl-hmac-authentication.patch
|
||||
Patch5: pam-1.5.1-pam_filter_close_file_after_controlling_tty.patch
|
||||
# https://github.com/linux-pam/linux-pam/commit/3234488f2c52a021eec87df1990d256314c21bff
|
||||
Patch6: pam-1.5.1-pam-limits-unlimited-value.patch
|
||||
# https://github.com/linux-pam/linux-pam/commit/a35e092e24ee7632346a0e1b4a203c04d4cd2c62
|
||||
Patch7: pam-1.5.1-pam-keyinit-thread-safe.patch
|
||||
|
||||
%global _pamlibdir %{_libdir}
|
||||
%global _moduledir %{_libdir}/security
|
||||
@ -120,6 +122,7 @@ cp %{SOURCE18} .
|
||||
%patch4 -p1 -b .timestamp-openssl-hmac-authentication
|
||||
%patch5 -p1 -b .pam_filter_close_file_after_controlling_tty
|
||||
%patch6 -p1 -b .pam-limits-unlimited-value
|
||||
%patch7 -p1 -b .pam-keyinit-thread-safe
|
||||
|
||||
autoreconf -i
|
||||
|
||||
@ -374,6 +377,9 @@ done
|
||||
%doc doc/sag/*.txt doc/sag/html
|
||||
|
||||
%changelog
|
||||
* Tue May 17 2022 Iker Pedrosa <ipedrosa@redhat.com> - 1.5.1-10
|
||||
- pam_keyinit: thread-safe implementation. Resolves: #2061696
|
||||
|
||||
* Thu Dec 2 2021 Iker Pedrosa <ipedrosa@redhat.com> - 1.5.1-9
|
||||
- pam_limits: "Unlimited" is not a valid value for RLIMIT_NOFILE. Resolves: #1989900
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user