From 16b6c08e992ff4de99b61921025d4fea88daa8dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89rico=20Rolim?= Date: Sun, 11 Oct 2020 00:43:04 -0300 Subject: [PATCH 1/2] pam: update to 1.4.0, update homepage, adopt. Also: - Cracklib is deprecated and disabled by default. - Added checkdepends. --- srcpkgs/pam/patches/fgetpwent_r.patch | 310 ++++++++++++++++++ srcpkgs/pam/patches/musl-fix-pam_exec.patch | 31 -- srcpkgs/pam/patches/opendir.patch | 120 +++++++ .../pam/patches/pam_unix_sys_resource.patch | 10 - srcpkgs/pam/patches/portability-fixes.patch | 44 --- srcpkgs/pam/template | 15 +- 6 files changed, 438 insertions(+), 92 deletions(-) create mode 100644 srcpkgs/pam/patches/fgetpwent_r.patch delete mode 100644 srcpkgs/pam/patches/musl-fix-pam_exec.patch create mode 100644 srcpkgs/pam/patches/opendir.patch delete mode 100644 srcpkgs/pam/patches/pam_unix_sys_resource.patch delete mode 100644 srcpkgs/pam/patches/portability-fixes.patch diff --git a/srcpkgs/pam/patches/fgetpwent_r.patch b/srcpkgs/pam/patches/fgetpwent_r.patch new file mode 100644 index 00000000000..9410e1eb6eb --- /dev/null +++ b/srcpkgs/pam/patches/fgetpwent_r.patch @@ -0,0 +1,310 @@ +Joint patch from upstream commits that removed the need for fgetpwent_r. + +Commit hashes: +* c9593778a6133bf29eb2f47c24cc6d2f5d729fc8 +* 0adbaeb273da1d45213134aa271e95987103281c +* efd2a79c11982d0feebebbf740506c9555120b97 (security fix for the function) + +diff --git a/libpam/Makefile.am b/libpam/Makefile.am +index 9252a837..11a1f329 100644 +--- libpam/Makefile.am ++++ libpam/Makefile.am +@@ -35,6 +35,7 @@ libpam_la_SOURCES = pam_account.c pam_auth.c pam_data.c pam_delay.c \ + pam_misc.c pam_password.c pam_prelude.c \ + pam_session.c pam_start.c pam_strerror.c \ + pam_vprompt.c pam_syslog.c pam_dynamic.c pam_audit.c \ ++ pam_modutil_check_user.c \ + pam_modutil_cleanup.c pam_modutil_getpwnam.c pam_modutil_ioloop.c \ + pam_modutil_getgrgid.c pam_modutil_getpwuid.c pam_modutil_getgrnam.c \ + pam_modutil_getspnam.c pam_modutil_getlogin.c pam_modutil_ingroup.c \ +diff --git a/libpam/include/security/pam_modutil.h b/libpam/include/security/pam_modutil.h +index 3a6aec6a..33f87b90 100644 +--- libpam/include/security/pam_modutil.h ++++ libpam/include/security/pam_modutil.h +@@ -58,6 +58,11 @@ extern "C" { + + #include + ++extern int PAM_NONNULL((1,2)) ++pam_modutil_check_user_in_passwd(pam_handle_t *pamh, ++ const char *user_name, ++ const char *file_name); ++ + extern struct passwd * PAM_NONNULL((1,2)) + pam_modutil_getpwnam(pam_handle_t *pamh, const char *user); + +diff --git a/libpam/libpam.map b/libpam/libpam.map +index c9690a91..3cc7ef35 100644 +--- libpam/libpam.map ++++ libpam/libpam.map +@@ -82,3 +82,8 @@ LIBPAM_1.4 { + global: + pam_start_confdir; + } LIBPAM_1.0; ++ ++LIBPAM_MODUTIL_1.4.1 { ++ global: ++ pam_modutil_check_user_in_passwd; ++} LIBPAM_MODUTIL_1.3.2; +diff --git a/libpam/pam_modutil_check_user.c b/libpam/pam_modutil_check_user.c +new file mode 100644 +index 00000000..cf1bd1b5 +--- /dev/null ++++ libpam/pam_modutil_check_user.c +@@ -0,0 +1,92 @@ ++#include "pam_modutil_private.h" ++#include ++ ++#include ++#include ++#include ++ ++int ++pam_modutil_check_user_in_passwd(pam_handle_t *pamh, ++ const char *user_name, ++ const char *file_name) ++{ ++ int rc; ++ size_t user_len; ++ FILE *fp; ++ char line[BUFSIZ]; ++ ++ /* Validate the user name. */ ++ if ((user_len = strlen(user_name)) == 0) { ++ pam_syslog(pamh, LOG_NOTICE, "user name is not valid"); ++ return PAM_SERVICE_ERR; ++ } ++ ++ if (user_len > sizeof(line) - sizeof(":")) { ++ pam_syslog(pamh, LOG_NOTICE, "user name is too long"); ++ return PAM_SERVICE_ERR; ++ } ++ ++ if (strchr(user_name, ':') != NULL) { ++ /* ++ * "root:x" is not a local user name even if the passwd file ++ * contains a line starting with "root:x:". ++ */ ++ return PAM_PERM_DENIED; ++ } ++ ++ /* Open the passwd file. */ ++ if (file_name == NULL) { ++ file_name = "/etc/passwd"; ++ } ++ if ((fp = fopen(file_name, "r")) == NULL) { ++ pam_syslog(pamh, LOG_ERR, "error opening %s: %m", file_name); ++ return PAM_SERVICE_ERR; ++ } ++ ++ /* ++ * Scan the file using fgets() instead of fgetpwent_r() because ++ * the latter is not flexible enough in handling long lines ++ * in passwd files. ++ */ ++ rc = PAM_PERM_DENIED; ++ while (fgets(line, sizeof(line), fp) != NULL) { ++ size_t line_len; ++ const char *str; ++ ++ /* ++ * Does this line start with the user name ++ * followed by a colon? ++ */ ++ if (strncmp(user_name, line, user_len) == 0 && ++ line[user_len] == ':') { ++ rc = PAM_SUCCESS; ++ /* ++ * Continue reading the file to avoid timing attacks. ++ */ ++ } ++ /* Has a newline been read? */ ++ line_len = strlen(line); ++ if (line_len < sizeof(line) - 1 || ++ line[line_len - 1] == '\n') { ++ /* Yes, continue with the next line. */ ++ continue; ++ } ++ ++ /* No, read till the end of this line first. */ ++ while ((str = fgets(line, sizeof(line), fp)) != NULL) { ++ line_len = strlen(line); ++ if (line_len == 0 || ++ line[line_len - 1] == '\n') { ++ break; ++ } ++ } ++ if (str == NULL) { ++ /* fgets returned NULL, we are done. */ ++ break; ++ } ++ /* Continue with the next line. */ ++ } ++ ++ fclose(fp); ++ return rc; ++} +diff --git a/modules/pam_faillock/pam_faillock.c b/modules/pam_faillock/pam_faillock.c +index f592d0a2..71988d09 100644 +--- modules/pam_faillock/pam_faillock.c ++++ modules/pam_faillock/pam_faillock.c +@@ -71,8 +71,6 @@ + #define MAX_TIME_INTERVAL 604800 /* 7 days */ + #define FAILLOCK_CONF_MAX_LINELEN 1023 + +-#define PATH_PASSWD "/etc/passwd" +- + static const char default_faillock_conf[] = FAILLOCK_DEFAULT_CONF; + + struct options { +@@ -348,42 +346,7 @@ set_conf_opt(pam_handle_t *pamh, struct options *opts, const char *name, const c + static int + check_local_user (pam_handle_t *pamh, const char *user) + { +- struct passwd pw, *pwp; +- char buf[16384]; +- int found = 0; +- FILE *fp; +- int errn; +- +- fp = fopen(PATH_PASSWD, "r"); +- if (fp == NULL) { +- pam_syslog(pamh, LOG_ERR, "unable to open %s: %m", +- PATH_PASSWD); +- return -1; +- } +- +- for (;;) { +- errn = fgetpwent_r(fp, &pw, buf, sizeof (buf), &pwp); +- if (errn == ERANGE) { +- pam_syslog(pamh, LOG_WARNING, "%s contains very long lines; corrupted?", +- PATH_PASSWD); +- break; +- } +- if (errn != 0) +- break; +- if (strcmp(pwp->pw_name, user) == 0) { +- found = 1; +- break; +- } +- } +- +- fclose (fp); +- +- if (errn != 0 && errn != ENOENT) { +- pam_syslog(pamh, LOG_ERR, "unable to enumerate local accounts: %m"); +- return -1; +- } else { +- return found; +- } ++ return pam_modutil_check_user_in_passwd(pamh, user, NULL) == PAM_SUCCESS; + } + + static int +diff --git a/modules/pam_localuser/pam_localuser.c b/modules/pam_localuser/pam_localuser.c +index cb507524..a9f2233c 100644 +--- modules/pam_localuser/pam_localuser.c ++++ modules/pam_localuser/pam_localuser.c +@@ -45,92 +45,10 @@ + #include + + #include ++#include + #include + #include "pam_inline.h" + +-static int +-check_user_in_passwd(pam_handle_t *pamh, const char *user_name, +- const char *file_name) +-{ +- int rc; +- size_t user_len; +- FILE *fp; +- char line[BUFSIZ]; +- +- /* Validate the user name. */ +- if ((user_len = strlen(user_name)) == 0) { +- pam_syslog(pamh, LOG_NOTICE, "user name is not valid"); +- return PAM_SERVICE_ERR; +- } +- +- if (user_len > sizeof(line) - sizeof(":")) { +- pam_syslog(pamh, LOG_NOTICE, "user name is too long"); +- return PAM_SERVICE_ERR; +- } +- +- if (strchr(user_name, ':') != NULL) { +- /* +- * "root:x" is not a local user name even if the passwd file +- * contains a line starting with "root:x:". +- */ +- return PAM_PERM_DENIED; +- } +- +- /* Open the passwd file. */ +- if (file_name == NULL) { +- file_name = "/etc/passwd"; +- } +- if ((fp = fopen(file_name, "r")) == NULL) { +- pam_syslog(pamh, LOG_ERR, "error opening %s: %m", file_name); +- return PAM_SERVICE_ERR; +- } +- +- /* +- * Scan the file using fgets() instead of fgetpwent_r() because +- * the latter is not flexible enough in handling long lines +- * in passwd files. +- */ +- rc = PAM_PERM_DENIED; +- while (fgets(line, sizeof(line), fp) != NULL) { +- size_t line_len; +- const char *str; +- +- /* +- * Does this line start with the user name +- * followed by a colon? +- */ +- if (strncmp(user_name, line, user_len) == 0 && +- line[user_len] == ':') { +- rc = PAM_SUCCESS; +- break; +- } +- /* Has a newline been read? */ +- line_len = strlen(line); +- if (line_len < sizeof(line) - 1 || +- line[line_len - 1] == '\n') { +- /* Yes, continue with the next line. */ +- continue; +- } +- +- /* No, read till the end of this line first. */ +- while ((str = fgets(line, sizeof(line), fp)) != NULL) { +- line_len = strlen(line); +- if (line_len == 0 || +- line[line_len - 1] == '\n') { +- break; +- } +- } +- if (str == NULL) { +- /* fgets returned NULL, we are done. */ +- break; +- } +- /* Continue with the next line. */ +- } +- +- fclose(fp); +- return rc; +-} +- + int + pam_sm_authenticate(pam_handle_t *pamh, int flags UNUSED, + int argc, const char **argv) +@@ -173,7 +91,7 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags UNUSED, + return rc == PAM_CONV_AGAIN ? PAM_INCOMPLETE : rc; + } + +- return check_user_in_passwd(pamh, user_name, file_name); ++ return pam_modutil_check_user_in_passwd(pamh, user_name, file_name); + } + + int diff --git a/srcpkgs/pam/patches/musl-fix-pam_exec.patch b/srcpkgs/pam/patches/musl-fix-pam_exec.patch deleted file mode 100644 index b6b999faed7..00000000000 --- a/srcpkgs/pam/patches/musl-fix-pam_exec.patch +++ /dev/null @@ -1,31 +0,0 @@ ---- ./modules/pam_exec/pam_exec.c.orig -+++ ./modules/pam_exec/pam_exec.c -@@ -103,11 +103,14 @@ - int optargc; - const char *logfile = NULL; - const char *authtok = NULL; -+ char authtok_buf[PAM_MAX_RESP_SIZE+1]; -+ - pid_t pid; - int fds[2]; - int stdout_fds[2]; - FILE *stdout_file = NULL; - -+ memset(authtok_buf, 0, sizeof(authtok_buf)); - if (argc < 1) { - pam_syslog (pamh, LOG_ERR, - "This module needs at least one argument"); -@@ -178,11 +181,11 @@ - } - - pam_set_item (pamh, PAM_AUTHTOK, resp); -- authtok = strndupa (resp, PAM_MAX_RESP_SIZE); -+ authtok = strncpy(authtok_buf, resp, sizeof(authtok_buf)); - _pam_drop (resp); - } - else -- authtok = strndupa (void_pass, PAM_MAX_RESP_SIZE); -+ authtok = strncpy(authtok_buf, void_pass, sizeof(authtok_buf)); - - if (pipe(fds) != 0) - { diff --git a/srcpkgs/pam/patches/opendir.patch b/srcpkgs/pam/patches/opendir.patch new file mode 100644 index 00000000000..b5818441762 --- /dev/null +++ b/srcpkgs/pam/patches/opendir.patch @@ -0,0 +1,120 @@ +Revert https://github.com/linux-pam/linux-pam/commit/1b087edc7f05237bf5eccc405704cd82b848e761, +which can deadlock on musl due to using malloc() (through opendir()) in an AS-unsafe context. + +Tracked in https://github.com/linux-pam/linux-pam/issues/266 + +diff --git a/configure.ac b/configure.ac +index ea08a7a3..7e077ca8 100644 +--- configure.ac ++++ configure.ac +@@ -567,7 +567,7 @@ dnl Checks for header files. + AC_HEADER_DIRENT + AC_HEADER_STDC + AC_HEADER_SYS_WAIT +-AC_CHECK_HEADERS(fcntl.h limits.h malloc.h sys/file.h sys/ioctl.h sys/time.h syslog.h net/if.h termio.h unistd.h sys/fsuid.h inittypes.h sys/vfs.h linux/magic.h) ++AC_CHECK_HEADERS(fcntl.h limits.h malloc.h sys/file.h sys/ioctl.h sys/time.h syslog.h net/if.h termio.h unistd.h sys/fsuid.h inittypes.h) + + dnl For module/pam_lastlog + AC_CHECK_HEADERS(lastlog.h utmp.h utmpx.h) +diff --git a/libpam/pam_modutil_sanitize.c b/libpam/pam_modutil_sanitize.c +index 58b9537c..7579c5bd 100644 +--- libpam/pam_modutil_sanitize.c ++++ libpam/pam_modutil_sanitize.c +@@ -10,13 +10,6 @@ + #include + #include + #include +-#include +-#ifdef HAVE_SYS_VFS_H +-#include +-#endif +-#ifdef HAVE_LINUX_MAGIC_H +-#include +-#endif + + /* + * Creates a pipe, closes its write end, redirects fd to its read end. +@@ -91,69 +84,31 @@ redirect_out(pam_handle_t *pamh, enum pam_modutil_redirect_fd mode, + return fd; + } + +-/* Check if path is in a procfs. */ +-static int +-is_in_procfs(int fd) +-{ +-#if defined HAVE_SYS_VFS_H && defined PROC_SUPER_MAGIC +- struct statfs stfs; +- +- if (fstatfs(fd, &stfs) == 0) { +- if (stfs.f_type == PROC_SUPER_MAGIC) +- return 1; +- } else { +- return 0; +- } +-#endif /* HAVE_SYS_VFS_H && PROC_SUPER_MAGIC */ +- +- return -1; +-} +- + /* Closes all descriptors after stderr. */ + static void + close_fds(void) + { +- DIR *dir = NULL; +- struct dirent *dent; +- int dfd = -1; +- int fd; +- struct rlimit rlim; +- + /* + * An arbitrary upper limit for the maximum file descriptor number + * returned by RLIMIT_NOFILE. + */ +- const unsigned int MAX_FD_NO = 65535; ++ const int MAX_FD_NO = 65535; + + /* The lower limit is the same as for _POSIX_OPEN_MAX. */ +- const unsigned int MIN_FD_NO = 20; +- +- /* If /proc is mounted, we can optimize which fd can be closed. */ +- if ((dir = opendir("/proc/self/fd")) != NULL) { +- if ((dfd = dirfd(dir)) >= 0 && is_in_procfs(dfd) > 0) { +- while ((dent = readdir(dir)) != NULL) { +- fd = atoi(dent->d_name); +- if (fd > STDERR_FILENO && fd != dfd) +- close(fd); +- } +- } else { +- dfd = -1; +- } +- closedir(dir); +- } ++ const int MIN_FD_NO = 20; + +- /* If /proc isn't available, fallback to the previous behavior. */ +- if (dfd < 0) { +- if (getrlimit(RLIMIT_NOFILE, &rlim) || rlim.rlim_max > MAX_FD_NO) +- fd = MAX_FD_NO; +- else if (rlim.rlim_max < MIN_FD_NO) +- fd = MIN_FD_NO; +- else +- fd = rlim.rlim_max - 1; +- +- for (; fd > STDERR_FILENO; --fd) +- close(fd); +- } ++ int fd; ++ struct rlimit rlim; ++ ++ if (getrlimit(RLIMIT_NOFILE, &rlim) || rlim.rlim_max > MAX_FD_NO) ++ fd = MAX_FD_NO; ++ else if (rlim.rlim_max < MIN_FD_NO) ++ fd = MIN_FD_NO; ++ else ++ fd = rlim.rlim_max - 1; ++ ++ for (; fd > STDERR_FILENO; --fd) ++ close(fd); + } + + int diff --git a/srcpkgs/pam/patches/pam_unix_sys_resource.patch b/srcpkgs/pam/patches/pam_unix_sys_resource.patch deleted file mode 100644 index 21f313b3584..00000000000 --- a/srcpkgs/pam/patches/pam_unix_sys_resource.patch +++ /dev/null @@ -1,10 +0,0 @@ ---- modules/pam_unix/pam_unix_acct.c.orig 2012-07-09 15:01:11.592269364 +0200 -+++ modules/pam_unix/pam_unix_acct.c 2012-07-09 15:01:54.615228076 +0200 -@@ -47,6 +47,7 @@ - #include /* for time() */ - #include - #include -+#include /* for RLIMIT_NOFILE */ - - #include - diff --git a/srcpkgs/pam/patches/portability-fixes.patch b/srcpkgs/pam/patches/portability-fixes.patch deleted file mode 100644 index 6f395008208..00000000000 --- a/srcpkgs/pam/patches/portability-fixes.patch +++ /dev/null @@ -1,44 +0,0 @@ ---- modules/pam_lastlog/pam_lastlog.c.orig 2014-01-11 12:56:15.735248391 +0100 -+++ modules/pam_lastlog/pam_lastlog.c 2014-01-11 12:57:33.142756424 +0100 -@@ -26,6 +26,7 @@ - #include - #include - #include -+#include - - #if defined(hpux) || defined(sunos) || defined(solaris) - # ifndef _PATH_LASTLOG -@@ -403,7 +404,9 @@ last_login_write(pam_handle_t *pamh, int - - if (announce & LASTLOG_WTMP) { - /* write wtmp entry for user */ -+#ifdef HAVE_LOGWTMP - logwtmp(last_login.ll_line, user, remote_host); -+#endif - } - - /* cleanup */ -@@ -713,7 +716,9 @@ pam_sm_close_session (pam_handle_t *pamh - terminal_line = get_tty(pamh); - - /* Wipe out utmp logout entry */ -+#ifdef HAVE_LOGWTMP - logwtmp(terminal_line, "", ""); -+#endif - - return PAM_SUCCESS; - } ---- modules/pam_rhosts/pam_rhosts.c.orig 2014-01-11 12:58:40.263196779 +0100 -+++ modules/pam_rhosts/pam_rhosts.c 2014-01-11 12:59:25.182491398 +0100 -@@ -113,8 +113,10 @@ int pam_sm_authenticate (pam_handle_t *p - - #ifdef HAVE_RUSEROK_AF - retval = ruserok_af (rhost, as_root, ruser, luser, PF_UNSPEC); --#else -+#elif HAVE_RUSEROK - retval = ruserok (rhost, as_root, ruser, luser); -+#else -+ retval = 1; - #endif - if (retval != 0) { - if (!opt_silent || opt_debug) diff --git a/srcpkgs/pam/template b/srcpkgs/pam/template index 161f96ad51f..68479771a1c 100644 --- a/srcpkgs/pam/template +++ b/srcpkgs/pam/template @@ -1,16 +1,17 @@ # Template file for 'pam' pkgname=pam -version=1.3.0 -revision=2 +version=1.4.0 +revision=1 wrksrc="Linux-PAM-$version" build_style=gnu-configure configure_args=" --libdir=/usr/lib --sbindir=/usr/bin --docdir=/usr/share/doc/pam - --disable-nis --disable-cracklib --disable-audit --disable-selinux + --disable-nis --disable-audit --disable-selinux --disable-regenerate-docu BUILD_CFLAGS=-Os BUILD_LDFLAGS=" hostmakedepends="automake gettext-devel flex libtool pkg-config" makedepends="libfl-devel db-devel" depends="pam-base" +checkdepends="${depends}" conf_files=" /etc/environment /etc/security/access.conf @@ -24,11 +25,11 @@ make_dirs=" /etc/security/namespace.d 0755 root root" lib32disabled=yes short_desc="Flexible mechanism for authenticating users" -maintainer="Orphaned " +maintainer="Érico Nogueira " license="BSD-3-Clause" -homepage="http://www.kernel.org/pub/linux/libs/pam/" -distfiles="http://linux-pam.org/library/Linux-PAM-${version}.tar.bz2" -checksum=241aed1ef522f66ed672719ecf2205ec513fd0075ed80cda8e086a5b1a01d1bb +homepage="https://github.com/linux-pam/linux-pam" +distfiles="${homepage}/releases/download/v${version}/Linux-PAM-${version}.tar.xz" +checksum=cd6d928c51e64139be3bdb38692c68183a509b83d4f2c221024ccd4bcddfd034 pre_configure() { case "$XBPS_TARGET_MACHINE" in From ead96432bf906ca0c00ba92fc40f78474e7e0ab1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89rico=20Rolim?= Date: Sun, 11 Oct 2020 00:45:08 -0300 Subject: [PATCH 2/2] pam-base: remove noarch. --- srcpkgs/pam-base/template | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/srcpkgs/pam-base/template b/srcpkgs/pam-base/template index 216cea3679f..00970e45331 100644 --- a/srcpkgs/pam-base/template +++ b/srcpkgs/pam-base/template @@ -1,8 +1,7 @@ # Template file for 'pam-base' pkgname=pam-base version=0.3 -revision=5 -archs=noarch +revision=6 short_desc="PAM base configuration files" maintainer="Orphaned " license="public domain"