From e634a3a9be9484ada6e93970dfaf0f055ca17332 Mon Sep 17 00:00:00 2001
From: "Dmitry V. Levin" <ldv@strace.io>
Date: Mon, 30 Dec 2024 08:00:00 +0000
Subject: pam_unix: do not overwrite the string returned by crypt_r

Given that the crypt_data storage passed to crypt_r is cleared
afterwards, there is no point in clearing the string returned by
crypt_r.  This also fixes the issue with those crypt_r implementations
that can return a pointer to read-only memory.

Resolves: https://github.com/linux-pam/linux-pam/issues/866
---
 modules/pam_unix/bigcrypt.c   | 4 ++++
 modules/pam_unix/passverify.c | 8 ++++----
 2 files changed, 8 insertions(+), 4 deletions(-)

diff --git a/modules/pam_unix/bigcrypt.c b/modules/pam_unix/bigcrypt.c
index 296e01f7..f960d978 100644
--- a/modules/pam_unix/bigcrypt.c
+++ b/modules/pam_unix/bigcrypt.c
@@ -116,7 +116,9 @@ char *bigcrypt(const char *key, const char *salt)
 	}
 	/* and place in the static area */
 	strncpy(cipher_ptr, tmp_ptr, 13);
+#ifndef HAVE_CRYPT_R
 	pam_overwrite_string(tmp_ptr);
+#endif
 	cipher_ptr += ESEGMENT_SIZE + SALT_SIZE;
 	plaintext_ptr += SEGMENT_SIZE;	/* first block of SEGMENT_SIZE */
 
@@ -149,7 +151,9 @@ char *bigcrypt(const char *key, const char *salt)
 
 			/* skip the salt for seg!=0 */
 			strncpy(cipher_ptr, (tmp_ptr + SALT_SIZE), ESEGMENT_SIZE);
+#ifndef HAVE_CRYPT_R
 			pam_overwrite_string(tmp_ptr);
+#endif
 
 			cipher_ptr += ESEGMENT_SIZE;
 			plaintext_ptr += SEGMENT_SIZE;
diff --git a/modules/pam_unix/passverify.c b/modules/pam_unix/passverify.c
index e8d0b91d..85e7841e 100644
--- a/modules/pam_unix/passverify.c
+++ b/modules/pam_unix/passverify.c
@@ -522,20 +522,20 @@ PAMH_ARG_DECL(char * create_password_hash,
 			   on(UNIX_BLOWFISH_PASS, ctrl) ? "blowfish" :
 			   on(UNIX_SHA256_PASS, ctrl) ? "sha256" :
 			   on(UNIX_SHA512_PASS, ctrl) ? "sha512" : algoid);
-		if(sp) {
-		   pam_overwrite_string(sp);
-		}
 #ifdef HAVE_CRYPT_R
 		pam_overwrite_object(cdata);
 		free(cdata);
+#else
+		pam_overwrite_string(sp);
 #endif
 		return NULL;
 	}
 	ret = strdup(sp);
-	pam_overwrite_string(sp);
 #ifdef HAVE_CRYPT_R
 	pam_overwrite_object(cdata);
 	free(cdata);
+#else
+	pam_overwrite_string(sp);
 #endif
 	return ret;
 }
-- 
cgit v1.2.3