[pam] pam_loginuid: make it return PAM_IGNORE in containers

Tomáš Mráz tmraz at fedoraproject.org
Thu May 22 09:49:21 UTC 2014


commit 1368ecb1ca2ef02213a06d8ed1e76dd20eef72c1
Author: Tomas Mraz <tmraz at fedoraproject.org>
Date:   Thu May 22 11:49:12 2014 +0200

    pam_loginuid: make it return PAM_IGNORE in containers

 pam-1.1.8-loginuid-container.patch |  151 ++++++++++++++++++++++++++++++++++++
 pam.spec                           |    7 ++-
 2 files changed, 157 insertions(+), 1 deletions(-)
---
diff --git a/pam-1.1.8-loginuid-container.patch b/pam-1.1.8-loginuid-container.patch
new file mode 100644
index 0000000..278829a
--- /dev/null
+++ b/pam-1.1.8-loginuid-container.patch
@@ -0,0 +1,151 @@
+diff -up Linux-PAM-1.1.8/modules/pam_loginuid/pam_loginuid.c.container Linux-PAM-1.1.8/modules/pam_loginuid/pam_loginuid.c
+--- Linux-PAM-1.1.8/modules/pam_loginuid/pam_loginuid.c.container	2013-06-18 16:11:21.000000000 +0200
++++ Linux-PAM-1.1.8/modules/pam_loginuid/pam_loginuid.c	2014-01-27 17:24:53.000000000 +0100
+@@ -47,25 +47,56 @@
+ 
+ /*
+  * This function writes the loginuid to the /proc system. It returns
+- * 0 on success and 1 on failure.
++ * PAM_SUCCESS on success,
++ * PAM_IGNORE when /proc/self/loginuid does not exist,
++ * PAM_SESSION_ERR in case of any other error.
+  */
+ static int set_loginuid(pam_handle_t *pamh, uid_t uid)
+ {
+-	int fd, count, rc = 0;
+-	char loginuid[24];
++	int fd, count, rc = PAM_SESSION_ERR;
++	char loginuid[24], buf[24];
++	static const char host_uid_map[] = "         0          0 4294967295\n";
++	char uid_map[sizeof(host_uid_map)];
++
++	/* loginuid in user namespaces currently isn't writable and in some
++	   case, not even readable, so consider any failure as ignorable (but try
++	   anyway, in case we hit a kernel which supports it). */
++	fd = open("/proc/self/uid_map", O_RDONLY);
++	if (fd >= 0) {
++		count = pam_modutil_read(fd, uid_map, sizeof(uid_map));
++		if (strncmp(uid_map, host_uid_map, count) != 0)
++			rc = PAM_IGNORE;
++		close(fd);
++	}
+ 
+-	count = snprintf(loginuid, sizeof(loginuid), "%lu", (unsigned long)uid);
+-	fd = open("/proc/self/loginuid", O_NOFOLLOW|O_WRONLY|O_TRUNC);
++	fd = open("/proc/self/loginuid", O_NOFOLLOW|O_RDWR);
+ 	if (fd < 0) {
+-		if (errno != ENOENT) {
+-			rc = 1;
+-			pam_syslog(pamh, LOG_ERR,
+-				   "Cannot open /proc/self/loginuid: %m");
++		if (errno == ENOENT) {
++			rc = PAM_IGNORE;
++		}
++		if (rc != PAM_IGNORE) {
++			pam_syslog(pamh, LOG_ERR, "Cannot open %s: %m",
++				   "/proc/self/loginuid");
+ 		}
+ 		return rc;
+ 	}
+-	if (pam_modutil_write(fd, loginuid, count) != count)
+-		rc = 1;
++
++	count = snprintf(loginuid, sizeof(loginuid), "%lu", (unsigned long)uid);
++	if (pam_modutil_read(fd, buf, sizeof(buf)) == count &&
++	    memcmp(buf, loginuid, count) == 0) {
++		rc = PAM_SUCCESS;
++		goto done;	/* already correct */
++	}
++	if (lseek(fd, 0, SEEK_SET) == 0 && ftruncate(fd, 0) == 0 &&
++	    pam_modutil_write(fd, loginuid, count) == count) {
++		rc = PAM_SUCCESS;
++	} else {
++		if (rc != PAM_IGNORE) {
++			pam_syslog(pamh, LOG_ERR, "Error writing %s: %m",
++				   "/proc/self/loginuid");
++		}
++	}
++ done:
+ 	close(fd);
+ 	return rc;
+ }
+@@ -165,6 +196,7 @@ _pam_loginuid(pam_handle_t *pamh, int fl
+ {
+         const char *user = NULL;
+ 	struct passwd *pwd;
++	int ret;
+ #ifdef HAVE_LIBAUDIT
+ 	int require_auditd = 0;
+ #endif
+@@ -183,9 +215,14 @@ _pam_loginuid(pam_handle_t *pamh, int fl
+ 		return PAM_SESSION_ERR;
+ 	}
+ 
+-	if (set_loginuid(pamh, pwd->pw_uid)) {
+-		pam_syslog(pamh, LOG_ERR, "set_loginuid failed\n");
+-		return PAM_SESSION_ERR;
++	ret = set_loginuid(pamh, pwd->pw_uid);
++	switch (ret) {
++		case PAM_SUCCESS:
++		case PAM_IGNORE:
++			break;
++		default:
++			pam_syslog(pamh, LOG_ERR, "set_loginuid failed");
++			return ret;
+ 	}
+ 
+ #ifdef HAVE_LIBAUDIT
+@@ -195,11 +232,12 @@ _pam_loginuid(pam_handle_t *pamh, int fl
+ 		argv++;
+ 	}
+ 
+-	if (require_auditd)
+-		return check_auditd();
+-	else
++	if (require_auditd) {
++		int rc = check_auditd();
++		return rc != PAM_SUCCESS ? rc : ret;
++	} else
+ #endif
+-		return PAM_SUCCESS;
++		return ret;
+ }
+ 
+ /*
+diff -up Linux-PAM-1.1.8/modules/pam_loginuid/pam_loginuid.8.xml.container Linux-PAM-1.1.8/modules/pam_loginuid/pam_loginuid.8.xml
+--- Linux-PAM-1.1.8/modules/pam_loginuid/pam_loginuid.8.xml.container	2013-06-18 16:11:21.000000000 +0200
++++ Linux-PAM-1.1.8/modules/pam_loginuid/pam_loginuid.8.xml	2014-05-22 11:33:14.000000000 +0200
+@@ -69,14 +69,31 @@
+     <para>
+       <variablelist>
+         <varlistentry>
++          <term>PAM_SUCCESS</term>
++          <listitem>
++            <para>
++              The loginuid value is set and auditd is running if check requested.
++            </para>
++          </listitem>
++        </varlistentry>
++        <varlistentry>
++          <term>PAM_IGNORE</term>
++          <listitem>
++            <para>
++              The /proc/self/loginuid file is not present on the system or the
++              login process runs inside uid namespace and kernel does not support
++              overwriting loginuid.
++            </para>
++          </listitem>
++        </varlistentry>
++        <varlistentry>
+           <term>PAM_SESSION_ERR</term>
+           <listitem>
+             <para>
+-              An error occurred during session management.
++              Any other error prevented setting loginuid or auditd is not running.
+             </para>
+           </listitem>
+         </varlistentry>
+-
+       </variablelist>
+     </para>
+   </refsect1>
diff --git a/pam.spec b/pam.spec
index 930e340..10c8b3a 100644
--- a/pam.spec
+++ b/pam.spec
@@ -3,7 +3,7 @@
 Summary: An extensible library which provides authentication for applications
 Name: pam
 Version: 1.1.8
-Release: 10%{?dist}
+Release: 11%{?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+.
@@ -47,6 +47,7 @@ Patch33: pam-1.1.8-translation-updates.patch
 Patch34: pam-1.1.8-canonicalize-username.patch
 Patch35: pam-1.1.8-cve-2013-7041.patch
 Patch36: pam-1.1.8-cve-2014-2583.patch
+Patch37: pam-1.1.8-loginuid-container.patch
 
 %define _pamlibdir %{_libdir}
 %define _moduledir %{_libdir}/security
@@ -127,6 +128,7 @@ mv pam-redhat-%{pam_redhat_version}/* modules
 %patch34 -p1 -b .canonicalize
 %patch35 -p1 -b .case
 %patch36 -p1 -b .timestamp-ruser
+%patch37 -p1 -b .container
 
 %build
 autoreconf -i
@@ -375,6 +377,9 @@ fi
 %doc doc/adg/*.txt doc/adg/html
 
 %changelog
+* Thu May 22 2014 Tomáš Mráz <tmraz at redhat.com> 1.1.8-11
+- pam_loginuid: make it return PAM_IGNORE in containers
+
 * Mon Mar 31 2014 Tomáš Mráz <tmraz at redhat.com> 1.1.8-10
 - fix CVE-2014-2583: potential path traversal issue in pam_timestamp
 


More information about the scm-commits mailing list