8c7ed8
From b6f73810a2e7afd02a231e2dfa14b05752c83db7 Mon Sep 17 00:00:00 2001
8c7ed8
From: "Dmitry V. Levin" <ldv@altlinux.org>
8c7ed8
Date: Wed, 26 Feb 2020 19:20:58 +0000
8c7ed8
Subject: [PATCH] pam_modutil_sanitize_helper_fds: fix SIGPIPE effect of
8c7ed8
 PAM_MODUTIL_PIPE_FD
8c7ed8
8c7ed8
When pam_modutil_sanitize_helper_fds() is invoked with
8c7ed8
PAM_MODUTIL_PIPE_FD to provide a dummy pipe descriptor for stdout
8c7ed8
or stderr, it closes the read end of the newly created dummy pipe.
8c7ed8
The negative side effect of this approach is that any write to such
8c7ed8
descriptor triggers a SIGPIPE.  Avoid this by closing the write end of
8c7ed8
the dummy pipe and using its read end as a dummy pipe descriptor for
8c7ed8
output.  Any read from such descriptor returns 0, and any write just
8c7ed8
fails with EBADF, which should work better with unprepared writers.
8c7ed8
8c7ed8
* libpam/pam_modutil_sanitize.c (redirect_out_pipe): Remove.
8c7ed8
(redirect_out): Call redirect_in_pipe instead of redirect_out_pipe.
8c7ed8
8c7ed8
Fixes: b0ec5d1e ("Introduce pam_modutil_sanitize_helper_fds")
8c7ed8
---
8c7ed8
 libpam/pam_modutil_sanitize.c | 30 +-----------------------------
8c7ed8
 1 file changed, 1 insertion(+), 29 deletions(-)
8c7ed8
8c7ed8
diff --git a/libpam/pam_modutil_sanitize.c b/libpam/pam_modutil_sanitize.c
8c7ed8
index 605c859d..58b9537c 100644
8c7ed8
--- a/libpam/pam_modutil_sanitize.c
8c7ed8
+++ b/libpam/pam_modutil_sanitize.c
8c7ed8
@@ -46,34 +46,6 @@ redirect_in_pipe(pam_handle_t *pamh, int fd, const char *name)
8c7ed8
 	return fd;
8c7ed8
 }
8c7ed8
 
8c7ed8
-/*
8c7ed8
- * Creates a pipe, closes its read end, redirects fd to its write end.
8c7ed8
- * Returns fd on success, -1 otherwise.
8c7ed8
- */
8c7ed8
-static int
8c7ed8
-redirect_out_pipe(pam_handle_t *pamh, int fd, const char *name)
8c7ed8
-{
8c7ed8
-	int out[2];
8c7ed8
-
8c7ed8
-	if (pipe(out) < 0) {
8c7ed8
-		pam_syslog(pamh, LOG_ERR, "Could not create pipe: %m");
8c7ed8
-		return -1;
8c7ed8
-	}
8c7ed8
-
8c7ed8
-	close(out[0]);
8c7ed8
-
8c7ed8
-	if (out[1] == fd)
8c7ed8
-		return fd;
8c7ed8
-
8c7ed8
-	if (dup2(out[1], fd) != fd) {
8c7ed8
-		pam_syslog(pamh, LOG_ERR, "dup2 of %s failed: %m", name);
8c7ed8
-		fd = -1;
8c7ed8
-	}
8c7ed8
-
8c7ed8
-	close(out[1]);
8c7ed8
-	return fd;
8c7ed8
-}
8c7ed8
-
8c7ed8
 /*
8c7ed8
  * Opens /dev/null for writing, redirects fd there.
8c7ed8
  * Returns fd on success, -1 otherwise.
8c7ed8
@@ -106,7 +78,7 @@ redirect_out(pam_handle_t *pamh, enum pam_modutil_redirect_fd mode,
8c7ed8
 {
8c7ed8
 	switch (mode) {
8c7ed8
 		case PAM_MODUTIL_PIPE_FD:
8c7ed8
-			if (redirect_out_pipe(pamh, fd, name) < 0)
8c7ed8
+			if (redirect_in_pipe(pamh, fd, name) < 0)
8c7ed8
 				return -1;
8c7ed8
 			break;
8c7ed8
 		case PAM_MODUTIL_NULL_FD:
8c7ed8
-- 
8c7ed8
2.25.3
8c7ed8