import CS pam-1.5.1-19.el9

This commit is contained in:
eabdullin 2024-03-28 11:21:45 +00:00
parent 6efd6b63ee
commit 0727581ebe
7 changed files with 569 additions and 1 deletions

View File

@ -0,0 +1,144 @@
From 244b46908df930626535c0cd7c2867407fe8714a Mon Sep 17 00:00:00 2001
From: Thorsten Kukuk <kukuk@suse.com>
Date: Tue, 14 Feb 2023 14:57:40 +0100
Subject: [PATCH] libpam: use getlogin() from libc and not utmp
utmp uses 32bit time_t for compatibility with 32bit userland on some
64bit systems and is thus not Y2038 safe. Use getlogin() from libc
which avoids using utmp and is more safe than the old utmp-based
implementation by using /proc/self/loginuid.
* libpam/pam_modutil_getlogin.c: Use getlogin() instead of parsing utmp
---
libpam/pam_modutil_getlogin.c | 52 ++++++++---------------------------
1 file changed, 11 insertions(+), 41 deletions(-)
diff --git a/libpam/pam_modutil_getlogin.c b/libpam/pam_modutil_getlogin.c
index 04a20fd8..633dd676 100644
--- a/libpam/pam_modutil_getlogin.c
+++ b/libpam/pam_modutil_getlogin.c
@@ -10,7 +10,6 @@
#include <stdlib.h>
#include <unistd.h>
-#include <utmp.h>
#define _PAMMODUTIL_GETLOGIN "_pammodutil_getlogin"
@@ -19,62 +18,33 @@ pam_modutil_getlogin(pam_handle_t *pamh)
{
int status;
const void *logname;
- const void *void_curr_tty;
- const char *curr_tty;
char *curr_user;
- struct utmp *ut, line;
+ size_t curr_user_len;
status = pam_get_data(pamh, _PAMMODUTIL_GETLOGIN, &logname);
if (status == PAM_SUCCESS) {
return logname;
}
- status = pam_get_item(pamh, PAM_TTY, &void_curr_tty);
- if ((status != PAM_SUCCESS) || (void_curr_tty == NULL))
- curr_tty = ttyname(0);
- else
- curr_tty = (const char*)void_curr_tty;
-
- if (curr_tty == NULL) {
- return NULL;
- }
-
- if (curr_tty[0] == '/') { /* full path */
- const char *t;
- curr_tty++;
- if ((t = strchr(curr_tty, '/')) != NULL) {
- curr_tty = t + 1;
- }
+ logname = getlogin();
+ if (logname == NULL) {
+ return NULL;
}
- logname = NULL;
- setutent();
- strncpy(line.ut_line, curr_tty, sizeof(line.ut_line));
-
- if ((ut = getutline(&line)) == NULL) {
- goto clean_up_and_go_home;
- }
-
- curr_user = calloc(sizeof(line.ut_user)+1, 1);
+ curr_user_len = strlen(logname)+1;
+ curr_user = calloc(curr_user_len, 1);
if (curr_user == NULL) {
- goto clean_up_and_go_home;
+ return NULL;
}
- strncpy(curr_user, ut->ut_user, sizeof(ut->ut_user));
- /* calloc already zeroed the memory */
+ memcpy(curr_user, logname, curr_user_len);
status = pam_set_data(pamh, _PAMMODUTIL_GETLOGIN, curr_user,
pam_modutil_cleanup);
if (status != PAM_SUCCESS) {
- free(curr_user);
- goto clean_up_and_go_home;
+ free(curr_user);
+ return NULL;
}
- logname = curr_user;
-
-clean_up_and_go_home:
-
- endutent();
-
- return logname;
+ return curr_user;
}
--
2.43.0
From f26d873435be9f35fa7953493cc07a9bc4e31876 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= <cgzones@googlemail.com>
Date: Sat, 18 Feb 2023 14:37:04 +0100
Subject: [PATCH] libpam: simplify string copying using strdup
---
libpam/pam_modutil_getlogin.c | 6 +-----
1 file changed, 1 insertion(+), 5 deletions(-)
diff --git a/libpam/pam_modutil_getlogin.c b/libpam/pam_modutil_getlogin.c
index 633dd676..2e7a0116 100644
--- a/libpam/pam_modutil_getlogin.c
+++ b/libpam/pam_modutil_getlogin.c
@@ -19,7 +19,6 @@ pam_modutil_getlogin(pam_handle_t *pamh)
int status;
const void *logname;
char *curr_user;
- size_t curr_user_len;
status = pam_get_data(pamh, _PAMMODUTIL_GETLOGIN, &logname);
if (status == PAM_SUCCESS) {
@@ -31,14 +30,11 @@ pam_modutil_getlogin(pam_handle_t *pamh)
return NULL;
}
- curr_user_len = strlen(logname)+1;
- curr_user = calloc(curr_user_len, 1);
+ curr_user = strdup(logname);
if (curr_user == NULL) {
return NULL;
}
- memcpy(curr_user, logname, curr_user_len);
-
status = pam_set_data(pamh, _PAMMODUTIL_GETLOGIN, curr_user,
pam_modutil_cleanup);
if (status != PAM_SUCCESS) {
--
2.43.0

View File

@ -0,0 +1,168 @@
diff -up Linux-PAM-1.5.1/modules/pam_access/pam_access.c.access-handle-hostnames Linux-PAM-1.5.1/modules/pam_access/pam_access.c
--- Linux-PAM-1.5.1/modules/pam_access/pam_access.c.access-handle-hostnames 2020-11-25 17:57:02.000000000 +0100
+++ Linux-PAM-1.5.1/modules/pam_access/pam_access.c 2024-01-22 15:56:09.977868880 +0100
@@ -662,7 +662,7 @@ from_match (pam_handle_t *pamh UNUSED, c
}
}
} else {
- /* Assume network/netmask with a IP of a host. */
+ /* Assume network/netmask, IP address or hostname. */
if (network_netmask_match(pamh, tok, string, item))
return YES;
}
@@ -684,7 +684,7 @@ string_match (pam_handle_t *pamh, const
/*
* If the token has the magic value "ALL" the match always succeeds.
* Otherwise, return YES if the token fully matches the string.
- * "NONE" token matches NULL string.
+ * "NONE" token matches NULL string.
*/
if (strcasecmp(tok, "ALL") == 0) { /* all: always matches */
@@ -702,7 +702,8 @@ string_match (pam_handle_t *pamh, const
/* network_netmask_match - match a string against one token
* where string is a hostname or ip (v4,v6) address and tok
- * represents either a single ip (v4,v6) address or a network/netmask
+ * represents either a hostname, a single ip (v4,v6) address
+ * or a network/netmask
*/
static int
network_netmask_match (pam_handle_t *pamh,
@@ -711,10 +712,12 @@ network_netmask_match (pam_handle_t *pam
char *netmask_ptr;
char netmask_string[MAXHOSTNAMELEN + 1];
int addr_type;
+ struct addrinfo *ai = NULL;
if (item->debug)
- pam_syslog (pamh, LOG_DEBUG,
+ pam_syslog (pamh, LOG_DEBUG,
"network_netmask_match: tok=%s, item=%s", tok, string);
+
/* OK, check if tok is of type addr/mask */
if ((netmask_ptr = strchr(tok, '/')) != NULL)
{
@@ -748,54 +751,108 @@ network_netmask_match (pam_handle_t *pam
netmask_ptr = number_to_netmask(netmask, addr_type,
netmask_string, MAXHOSTNAMELEN);
}
- }
+
+ /*
+ * Construct an addrinfo list from the IP address.
+ * This should not fail as the input is a correct IP address...
+ */
+ if (getaddrinfo (tok, NULL, NULL, &ai) != 0)
+ {
+ return NO;
+ }
+ }
else
- /* NO, then check if it is only an addr */
- if (isipaddr(tok, NULL, NULL) != YES)
+ {
+ /*
+ * It is either an IP address or a hostname.
+ * Let getaddrinfo sort everything out
+ */
+ if (getaddrinfo (tok, NULL, NULL, &ai) != 0)
{
+ pam_syslog(pamh, LOG_ERR, "cannot resolve hostname \"%s\"", tok);
+
return NO;
}
+ netmask_ptr = NULL;
+ }
if (isipaddr(string, NULL, NULL) != YES)
{
- /* Assume network/netmask with a name of a host. */
struct addrinfo hint;
+ /* Assume network/netmask with a name of a host. */
memset (&hint, '\0', sizeof (hint));
hint.ai_flags = AI_CANONNAME;
hint.ai_family = AF_UNSPEC;
if (item->gai_rv != 0)
+ {
+ freeaddrinfo(ai);
return NO;
+ }
else if (!item->res &&
(item->gai_rv = getaddrinfo (string, NULL, &hint, &item->res)) != 0)
+ {
+ freeaddrinfo(ai);
return NO;
+ }
else
{
struct addrinfo *runp = item->res;
+ struct addrinfo *runp1;
while (runp != NULL)
{
char buf[INET6_ADDRSTRLEN];
- DIAG_PUSH_IGNORE_CAST_ALIGN;
- inet_ntop (runp->ai_family,
- runp->ai_family == AF_INET
- ? (void *) &((struct sockaddr_in *) runp->ai_addr)->sin_addr
- : (void *) &((struct sockaddr_in6 *) runp->ai_addr)->sin6_addr,
- buf, sizeof (buf));
- DIAG_POP_IGNORE_CAST_ALIGN;
+ if (getnameinfo (runp->ai_addr, runp->ai_addrlen, buf, sizeof (buf), NULL, 0, NI_NUMERICHOST) != 0)
+ {
+ freeaddrinfo(ai);
+ return NO;
+ }
- if (are_addresses_equal(buf, tok, netmask_ptr))
+ for (runp1 = ai; runp1 != NULL; runp1 = runp1->ai_next)
{
- return YES;
+ char buf1[INET6_ADDRSTRLEN];
+
+ if (runp->ai_family != runp1->ai_family)
+ continue;
+
+ if (getnameinfo (runp1->ai_addr, runp1->ai_addrlen, buf1, sizeof (buf1), NULL, 0, NI_NUMERICHOST) != 0)
+ {
+ freeaddrinfo(ai);
+ return NO;
+ }
+
+ if (are_addresses_equal (buf, buf1, netmask_ptr))
+ {
+ freeaddrinfo(ai);
+ return YES;
+ }
}
runp = runp->ai_next;
}
}
}
else
- return (are_addresses_equal(string, tok, netmask_ptr));
+ {
+ struct addrinfo *runp1;
+
+ for (runp1 = ai; runp1 != NULL; runp1 = runp1->ai_next)
+ {
+ char buf1[INET6_ADDRSTRLEN];
+
+ (void) getnameinfo (runp1->ai_addr, runp1->ai_addrlen, buf1, sizeof (buf1), NULL, 0, NI_NUMERICHOST);
+
+ if (are_addresses_equal(string, buf1, netmask_ptr))
+ {
+ freeaddrinfo(ai);
+ return YES;
+ }
+ }
+ }
+
+ freeaddrinfo(ai);
return NO;
}

View File

@ -0,0 +1,72 @@
From c85513220c1bd3150e39c6277422d29cfa44acc7 Mon Sep 17 00:00:00 2001
From: Steve Grubb <sgrubb@redhat.com>
Date: Thu, 27 Jul 2023 13:14:42 -0400
Subject: [PATCH 1/2] pam_faillock: fix formatting of audit messages
pam_faillock uses audit_log_user_message to write to the audit system.
It does not take an op argument, so you have to add one yourself. Otherwise
the pam_faillock part of the message is lost because it's not in key=value
format.
Also, we can't use uid in that event because the kernel already adds that
field. What we normally do is use 'suid' (meaning sender uid) as the
field name.
---
modules/pam_faillock/pam_faillock.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/modules/pam_faillock/pam_faillock.c b/modules/pam_faillock/pam_faillock.c
index ca1c7035..a89909ab 100644
--- a/modules/pam_faillock/pam_faillock.c
+++ b/modules/pam_faillock/pam_faillock.c
@@ -248,7 +248,7 @@ check_tally(pam_handle_t *pamh, struct options *opts, struct tally_data *tallies
(void)pam_get_item(pamh, PAM_TTY, &tty);
(void)pam_get_item(pamh, PAM_RHOST, &rhost);
- snprintf(buf, sizeof(buf), "pam_faillock uid=%u ", opts->uid);
+ snprintf(buf, sizeof(buf), "op=pam_faillock suid=%u ", opts->uid);
audit_log_user_message(audit_fd, AUDIT_RESP_ACCT_UNLOCK_TIMED, buf,
rhost, NULL, tty, 1);
}
@@ -364,7 +364,7 @@ write_tally(pam_handle_t *pamh, struct options *opts, struct tally_data *tallies
errno == EAFNOSUPPORT))
return PAM_SYSTEM_ERR;
- snprintf(buf, sizeof(buf), "pam_faillock uid=%u ", opts->uid);
+ snprintf(buf, sizeof(buf), "op=pam_faillock suid=%u ", opts->uid);
audit_log_user_message(audit_fd, AUDIT_ANOM_LOGIN_FAILURES, buf,
NULL, NULL, NULL, 1);
--
2.41.0
From 1648734a69c31e9ce834da70144ac9a453296807 Mon Sep 17 00:00:00 2001
From: Steve Grubb <sgrubb@redhat.com>
Date: Fri, 4 Aug 2023 17:45:45 -0400
Subject: [PATCH 2/2] pam_selinux: fix formatting of audit messages
pam_selinux uses audit_log_user_message to write to the audit system.
It does not take an op argument, so you have to add one yourself. Otherwise
the pam_selinux part of the message is lost because it's not in key=value
format.
---
modules/pam_selinux/pam_selinux.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/modules/pam_selinux/pam_selinux.c b/modules/pam_selinux/pam_selinux.c
index e52e0fc4..713b3f73 100644
--- a/modules/pam_selinux/pam_selinux.c
+++ b/modules/pam_selinux/pam_selinux.c
@@ -97,7 +97,7 @@ send_audit_message(const pam_handle_t *pamh, int success, const char *default_co
pam_syslog(pamh, LOG_ERR, "Error translating selected context '%s'.", selected_context);
selected_raw = NULL;
}
- if (asprintf(&msg, "pam: default-context=%s selected-context=%s",
+ if (asprintf(&msg, "op=pam_selinux default-context=%s selected-context=%s",
default_raw ? default_raw : (default_context ? default_context : "?"),
selected_raw ? selected_raw : (selected_context ? selected_context : "?")) < 0) {
msg = NULL; /* asprintf leaves msg in undefined state on failure */
--
2.41.0

View File

@ -0,0 +1,36 @@
From d54870f993e97fe75e2cd0470a3701d5af22877c Mon Sep 17 00:00:00 2001
From: Changqing Li <changqing.li@windriver.com>
Date: Tue, 12 Jan 2021 14:45:34 +0800
Subject: [PATCH] faillock: create tallydir before creating tallyfile
The default tallydir is "/var/run/faillock", and this default
tallydir may not exist.
Function open may fail as tallydir does not exist when creating
the tallyfile. Therefore, faillock will not work well.
Fix this problem by creating tallydir before creating tallyfile
when the tallydir does not exist.
Signed-off-by: Changqing Li <changqing.li@windriver.com>
---
modules/pam_faillock/faillock.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/modules/pam_faillock/faillock.c b/modules/pam_faillock/faillock.c
index 4ea94cbe..091f253a 100644
--- a/modules/pam_faillock/faillock.c
+++ b/modules/pam_faillock/faillock.c
@@ -74,6 +74,9 @@ open_tally (const char *dir, const char *user, uid_t uid, int create)
if (create) {
flags |= O_CREAT;
+ if (access(dir, F_OK) != 0) {
+ mkdir(dir, 0755);
+ }
}
fd = open(path, flags, 0660);
--
2.43.0

View File

@ -0,0 +1,55 @@
diff -up Linux-PAM-1.5.1/configure.ac.libpam-close-range Linux-PAM-1.5.1/configure.ac
--- Linux-PAM-1.5.1/configure.ac.libpam-close-range 2023-11-10 10:35:00.142833269 +0100
+++ Linux-PAM-1.5.1/configure.ac 2023-11-10 10:36:29.158987392 +0100
@@ -552,6 +552,7 @@ AC_CHECK_FUNCS(inet_ntop inet_pton innet
AC_CHECK_FUNCS(quotactl)
AC_CHECK_FUNCS(unshare)
AC_CHECK_FUNCS([ruserok_af ruserok], [break])
+AC_CHECK_FUNCS(close_range)
BACKUP_LIBS=$LIBS
LIBS="$LIBS -lutil"
AC_CHECK_FUNCS([logwtmp])
diff -up Linux-PAM-1.5.1/libpam/pam_modutil_sanitize.c.libpam-close-range Linux-PAM-1.5.1/libpam/pam_modutil_sanitize.c
--- Linux-PAM-1.5.1/libpam/pam_modutil_sanitize.c.libpam-close-range 2020-11-25 17:57:02.000000000 +0100
+++ Linux-PAM-1.5.1/libpam/pam_modutil_sanitize.c 2023-11-10 10:35:00.142833269 +0100
@@ -11,6 +11,10 @@
#include <syslog.h>
#include <sys/resource.h>
+#ifndef CLOSE_RANGE_UNSHARE
+#define CLOSE_RANGE_UNSHARE (1U << 1)
+#endif /* CLOSE_RANGE_UNSHARE */
+
/*
* Creates a pipe, closes its write end, redirects fd to its read end.
* Returns fd on success, -1 otherwise.
@@ -84,9 +88,8 @@ redirect_out(pam_handle_t *pamh, enum pa
return fd;
}
-/* Closes all descriptors after stderr. */
static void
-close_fds(void)
+close_fds_iteratively(void)
{
/*
* An arbitrary upper limit for the maximum file descriptor number
@@ -111,6 +114,18 @@ close_fds(void)
close(fd);
}
+/* Closes all descriptors after stderr. */
+static void
+close_fds(void)
+{
+#ifdef HAVE_CLOSE_RANGE
+ if (close_range(STDERR_FILENO+1, -1U, CLOSE_RANGE_UNSHARE) == 0)
+ return;
+#endif /* HAVE_CLOSE_RANGE */
+
+ close_fds_iteratively();
+}
+
int
pam_modutil_sanitize_helper_fds(pam_handle_t *pamh,
enum pam_modutil_redirect_fd stdin_mode,

View File

@ -0,0 +1,58 @@
From 031bb5a5d0d950253b68138b498dc93be69a64cb Mon Sep 17 00:00:00 2001
From: Matthias Gerstner <matthias.gerstner@suse.de>
Date: Wed, 27 Dec 2023 14:01:59 +0100
Subject: [PATCH] pam_namespace: protect_dir(): use O_DIRECTORY to prevent
local DoS situations
Without O_DIRECTORY the path crawling logic is subject to e.g. FIFOs
being placed in user controlled directories, causing the PAM module to
block indefinitely during `openat()`.
Pass O_DIRECTORY to cause the `openat()` to fail if the path does not
refer to a directory.
With this the check whether the final path element is a directory
becomes unnecessary, drop it.
---
modules/pam_namespace/pam_namespace.c | 18 +-----------------
1 file changed, 1 insertion(+), 17 deletions(-)
diff --git a/modules/pam_namespace/pam_namespace.c b/modules/pam_namespace/pam_namespace.c
index 2528cff8..f72d6718 100644
--- a/modules/pam_namespace/pam_namespace.c
+++ b/modules/pam_namespace/pam_namespace.c
@@ -1201,7 +1201,7 @@ static int protect_dir(const char *path, mode_t mode, int do_mkdir,
int dfd = AT_FDCWD;
int dfd_next;
int save_errno;
- int flags = O_RDONLY;
+ int flags = O_RDONLY | O_DIRECTORY;
int rv = -1;
struct stat st;
@@ -1255,22 +1255,6 @@ static int protect_dir(const char *path, mode_t mode, int do_mkdir,
rv = openat(dfd, dir, flags);
}
- if (rv != -1) {
- if (fstat(rv, &st) != 0) {
- save_errno = errno;
- close(rv);
- rv = -1;
- errno = save_errno;
- goto error;
- }
- if (!S_ISDIR(st.st_mode)) {
- close(rv);
- errno = ENOTDIR;
- rv = -1;
- goto error;
- }
- }
-
if (flags & O_NOFOLLOW) {
/* we are inside user-owned dir - protect */
if (protect_mount(rv, p, idata) == -1) {
--
2.43.0

View File

@ -3,7 +3,7 @@
Summary: An extensible library which provides authentication for applications
Name: pam
Version: 1.5.1
Release: 15%{?dist}
Release: 19%{?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+.
@ -51,6 +51,20 @@ Patch13: pam-1.5.1-pam-faillock-avoid-logging-erroneous.patch
# https://github.com/linux-pam/linux-pam/commit/55f206447a1e4ee26e307e7a9c069236e823b1a5
# https://github.com/linux-pam/linux-pam/commit/80bfda5962e5be3daa70e0fc8c75fc97d1c55121
Patch14: pam-1.5.1-pam-misc-configurable.patch
# https://github.com/linux-pam/linux-pam/commit/d6103b30050554d7b6ca6d55cb5b4ed3c9516663
Patch15: pam-1.5.1-libpam-close-range.patch
# https://github.com/linux-pam/linux-pam/commit/c85513220c1bd3150e39c6277422d29cfa44acc7
# https://github.com/linux-pam/linux-pam/commit/1648734a69c31e9ce834da70144ac9a453296807
Patch16: pam-1.5.1-audit-messages-formatting.patch
# https://github.com/linux-pam/linux-pam/commit/d54870f993e97fe75e2cd0470a3701d5af22877c
Patch17: pam-1.5.1-faillock-create-tallydir.patch
# https://github.com/linux-pam/linux-pam/commit/244b46908df930626535c0cd7c2867407fe8714a
# https://github.com/linux-pam/linux-pam/commit/f26d873435be9f35fa7953493cc07a9bc4e31876
Patch18: pam-1-5-1-libpam-getlogin.patch
# https://github.com/linux-pam/linux-pam/commit/23393bef92c1e768eda329813d7af55481c6ca9f
Patch19: pam-1.5.1-access-handle-hostnames.patch
# https://github.com/linux-pam/linux-pam/commit/031bb5a5d0d950253b68138b498dc93be69a64cb
Patch20: pam-1.5.1-namespace-protect-dir.patch
%global _pamlibdir %{_libdir}
%global _moduledir %{_libdir}/security
@ -147,6 +161,12 @@ cp %{SOURCE18} .
%patch12 -p1 -b .pam-faillock-clarify-missing-user
%patch13 -p1 -b .pam-faillock-avoid-logging-erroneous
%patch14 -p1 -b .pam-misc-configurable
%patch15 -p1 -b .libpam-close-range
%patch16 -p1 -b .audit-messages-formatting
%patch17 -p1 -b .faillock-create-tallydir
%patch18 -p1 -b .libpam-getlogin
%patch19 -p1 -b .access-handle-hostnames
%patch20 -p1 -b .namespace-protect-dir
autoreconf -i
@ -402,6 +422,21 @@ done
%doc doc/sag/*.txt doc/sag/html
%changelog
* Mon Feb 12 2024 Iker Pedrosa <ipedrosa@redhat.com> - 1.3.1-19
- pam_namespace: protect_dir(): use O_DIRECTORY to prevent local DoS
situations. CVE-2024-22365. Resolves: RHEL-21244
* Fri Jan 26 2024 Iker Pedrosa <ipedrosa@redhat.com> - 1.3.1-18
- libpam: use getlogin() from libc and not utmp. Resolves: RHEL-16727
- pam_access: handle hostnames in access.conf. Resolves: RHEL-22300
* Mon Jan 8 2024 Iker Pedrosa <ipedrosa@redhat.com> - 1.5.1-17
- pam_faillock: create tallydir before creating tallyfile. Resolves: RHEL-20943
* Fri Nov 10 2023 Iker Pedrosa <ipedrosa@redhat.com> - 1.5.1-16
- libpam: use close_range() to close file descriptors. Resolves: RHEL-5099
- fix formatting of audit messages. Resolves: RHEL-5100
* Mon Jun 26 2023 Iker Pedrosa <ipedrosa@redhat.com> - 1.5.1-15
- pam_misc: make length of misc_conv() configurable and set to 4096. Resolves: #2215007