From 9f19e7da7a014e022cdbba06accca171adef27e0 Mon Sep 17 00:00:00 2001
From: Christian Göttsche <cgzones@googlemail.com>
Date: Thu, 4 Jan 2024 18:23:59 +0100
Subject: pam_unix: set close-on-exec

Since the module operates on sensitive files set the close-on-exec flag,
to avoid file descriptor leaks if there is ever any sibling thread.

The fopen(3) mode "e" is supported in glibc since version 2.7 (released
in 2007), and ignored prior, see:
https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=65d834b0add966dbbdb5ed1e916c60b2b2d87f10
---
 modules/pam_unix/passverify.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

(limited to 'modules/pam_unix/passverify.c')

diff --git a/modules/pam_unix/passverify.c b/modules/pam_unix/passverify.c
index 60d9ceca..303929a4 100644
--- a/modules/pam_unix/passverify.c
+++ b/modules/pam_unix/passverify.c
@@ -400,7 +400,7 @@ crypt_make_salt(char *where, int length)
 	int fd;
 	int rv;
 
-	if ((rv = fd = open(PAM_PATH_RANDOMDEV, O_RDONLY)) != -1) {
+	if ((rv = fd = open(PAM_PATH_RANDOMDEV, O_RDONLY | O_CLOEXEC)) != -1) {
 		while ((rv = read(fd, where, length)) != length && errno == EINTR);
 		close (fd);
 	}
@@ -557,7 +557,7 @@ unix_selinux_confined(void)
     }
 
     /* let's try opening shadow read only */
-    if ((fd=open("/etc/shadow", O_RDONLY)) != -1) {
+    if ((fd=open("/etc/shadow", O_RDONLY | O_CLOEXEC)) != -1) {
         close(fd);
         confined = 0;
         return confined;
@@ -695,14 +695,14 @@ save_old_password(pam_handle_t *pamh, const char *forwho, const char *oldpass,
       freecon(passwd_context_raw);
     }
 #endif
-    pwfile = fopen(OPW_TMPFILE, "w");
+    pwfile = fopen(OPW_TMPFILE, "we");
     umask(oldmask);
     if (pwfile == NULL) {
       err = 1;
       goto done;
     }
 
-    opwfile = fopen(OLD_PASSWORDS_FILE, "r");
+    opwfile = fopen(OLD_PASSWORDS_FILE, "re");
     if (opwfile == NULL) {
 	fclose(pwfile);
       err = 1;
@@ -858,14 +858,14 @@ PAMH_ARG_DECL(int unix_update_passwd,
       freecon(passwd_context_raw);
     }
 #endif
-    pwfile = fopen(PW_TMPFILE, "w");
+    pwfile = fopen(PW_TMPFILE, "we");
     umask(oldmask);
     if (pwfile == NULL) {
       err = 1;
       goto done;
     }
 
-    opwfile = fopen("/etc/passwd", "r");
+    opwfile = fopen("/etc/passwd", "re");
     if (opwfile == NULL) {
 	fclose(pwfile);
 	err = 1;
@@ -983,14 +983,14 @@ PAMH_ARG_DECL(int unix_update_shadow,
       freecon(shadow_context_raw);
     }
 #endif
-    pwfile = fopen(SH_TMPFILE, "w");
+    pwfile = fopen(SH_TMPFILE, "we");
     umask(oldmask);
     if (pwfile == NULL) {
 	err = 1;
 	goto done;
     }
 
-    opwfile = fopen("/etc/shadow", "r");
+    opwfile = fopen("/etc/shadow", "re");
     if (opwfile == NULL) {
 	fclose(pwfile);
 	err = 1;
-- 
cgit v1.2.3