File pam_modutil_get-overwrite-password-at-free.patch of Package pam.40283

From e2fdc55d9d8d277c9395f96c3bf2938bacc84f62 Mon Sep 17 00:00:00 2001
From: Thorsten Kukuk <kukuk@suse.com>
Date: Thu, 14 Aug 2025 12:01:25 +0200
Subject: [PATCH] pam_modutil_get*: overwrite password at free (#846)

Make sure that the buffer containing encrypted passwords (struct group,
passwd and shadow) get's erased before free, so that they are not
available anymore if the memory get allocated again.

[vlefebvre: adjust context]
---
 libpam/pam_modutil_cleanup.c  | 40 +++++++++++++++++++++++++++++++++++
 libpam/pam_modutil_getgrgid.c |  2 +-
 libpam/pam_modutil_getgrnam.c |  2 +-
 libpam/pam_modutil_getpwnam.c |  2 +-
 libpam/pam_modutil_getpwuid.c |  2 +-
 libpam/pam_modutil_getspnam.c |  2 +-
 libpam/pam_modutil_private.h  |  9 ++++++++
 7 files changed, 54 insertions(+), 5 deletions(-)

Index: Linux-PAM-1.3.0/libpam/pam_modutil_cleanup.c
===================================================================
--- Linux-PAM-1.3.0.orig/libpam/pam_modutil_cleanup.c
+++ Linux-PAM-1.3.0/libpam/pam_modutil_cleanup.c
@@ -5,8 +5,12 @@
  */
 
 #include "pam_modutil_private.h"
+#include "pam_inline.h"
 
+#include <grp.h>
+#include <pwd.h>
 #include <stdlib.h>
+#include <shadow.h>
 
 void
 pam_modutil_cleanup (pam_handle_t *pamh UNUSED, void *data,
@@ -17,3 +21,39 @@ pam_modutil_cleanup (pam_handle_t *pamh
 	(void) free(data);
     }
 }
+
+void
+pam_modutil_cleanup_group (pam_handle_t *pamh UNUSED, void *data,
+			   int error_status UNUSED)
+{
+	struct group *gr = data;
+
+	if (gr && gr->gr_passwd)
+		pam_overwrite_string(gr->gr_passwd);
+
+	free(data);
+}
+
+void
+pam_modutil_cleanup_passwd (pam_handle_t *pamh UNUSED, void *data,
+			    int error_status UNUSED)
+{
+	struct passwd *pw = data;
+
+	if (pw && pw->pw_passwd)
+		pam_overwrite_string(pw->pw_passwd);
+
+	free(data);
+}
+
+void
+pam_modutil_cleanup_shadow (pam_handle_t *pamh UNUSED, void *data,
+			    int error_status UNUSED)
+{
+	struct spwd *sp = data;
+
+	if (sp && sp->sp_pwdp)
+		pam_overwrite_string(sp->sp_pwdp);
+
+	free(data);
+}
Index: Linux-PAM-1.3.0/libpam/pam_modutil_getgrgid.c
===================================================================
--- Linux-PAM-1.3.0.orig/libpam/pam_modutil_getgrgid.c
+++ Linux-PAM-1.3.0/libpam/pam_modutil_getgrgid.c
@@ -87,7 +87,7 @@ pam_modutil_getgrgid(pam_handle_t *pamh,
 		    status = PAM_NO_MODULE_DATA;
 	            if (pam_get_data(pamh, data_name, &ignore) != PAM_SUCCESS) {
 		        status = pam_set_data(pamh, data_name,
-					      result, pam_modutil_cleanup);
+					      result, pam_modutil_cleanup_group);
 		    }
 		    if (status == PAM_SUCCESS) {
 		        break;
Index: Linux-PAM-1.3.0/libpam/pam_modutil_getgrnam.c
===================================================================
--- Linux-PAM-1.3.0.orig/libpam/pam_modutil_getgrnam.c
+++ Linux-PAM-1.3.0/libpam/pam_modutil_getgrnam.c
@@ -76,7 +76,7 @@ pam_modutil_getgrnam(pam_handle_t *pamh,
 		    status = PAM_NO_MODULE_DATA;
 	            if (pam_get_data(pamh, data_name, &ignore) != PAM_SUCCESS) {
 		        status = pam_set_data(pamh, data_name,
-					      result, pam_modutil_cleanup);
+					      result, pam_modutil_cleanup_group);
 		    }
 		    if (status == PAM_SUCCESS) {
 		        break;
Index: Linux-PAM-1.3.0/libpam/pam_modutil_getpwnam.c
===================================================================
--- Linux-PAM-1.3.0.orig/libpam/pam_modutil_getpwnam.c
+++ Linux-PAM-1.3.0/libpam/pam_modutil_getpwnam.c
@@ -76,7 +76,7 @@ pam_modutil_getpwnam(pam_handle_t *pamh,
 		    status = PAM_NO_MODULE_DATA;
 	            if (pam_get_data(pamh, data_name, &ignore) != PAM_SUCCESS) {
 		        status = pam_set_data(pamh, data_name,
-					      result, pam_modutil_cleanup);
+					      result, pam_modutil_cleanup_passwd);
 		    }
 		    if (status == PAM_SUCCESS) {
 		        break;
Index: Linux-PAM-1.3.0/libpam/pam_modutil_getpwuid.c
===================================================================
--- Linux-PAM-1.3.0.orig/libpam/pam_modutil_getpwuid.c
+++ Linux-PAM-1.3.0/libpam/pam_modutil_getpwuid.c
@@ -87,7 +87,7 @@ pam_modutil_getpwuid(pam_handle_t *pamh,
 		    status = PAM_NO_MODULE_DATA;
 	            if (pam_get_data(pamh, data_name, &ignore) != PAM_SUCCESS) {
 		        status = pam_set_data(pamh, data_name,
-					      result, pam_modutil_cleanup);
+					      result, pam_modutil_cleanup_passwd);
 		    }
 		    if (status == PAM_SUCCESS) {
 		        break;
Index: Linux-PAM-1.3.0/libpam/pam_modutil_getspnam.c
===================================================================
--- Linux-PAM-1.3.0.orig/libpam/pam_modutil_getspnam.c
+++ Linux-PAM-1.3.0/libpam/pam_modutil_getspnam.c
@@ -76,7 +76,7 @@ pam_modutil_getspnam(pam_handle_t *pamh,
 		    status = PAM_NO_MODULE_DATA;
 	            if (pam_get_data(pamh, data_name, &ignore) != PAM_SUCCESS) {
 		        status = pam_set_data(pamh, data_name,
-					      result, pam_modutil_cleanup);
+					      result, pam_modutil_cleanup_shadow);
 		    }
 		    if (status == PAM_SUCCESS) {
 		        break;
Index: Linux-PAM-1.3.0/libpam/pam_modutil_private.h
===================================================================
--- Linux-PAM-1.3.0.orig/libpam/pam_modutil_private.h
+++ Linux-PAM-1.3.0/libpam/pam_modutil_private.h
@@ -20,5 +20,14 @@
 extern void
 pam_modutil_cleanup(pam_handle_t *pamh, void *data,
                     int error_status);
+extern void
+pam_modutil_cleanup_group(pam_handle_t *pamh, void *data,
+			  int error_status);
+extern void
+pam_modutil_cleanup_passwd(pam_handle_t *pamh, void *data,
+			   int error_status);
+extern void
+pam_modutil_cleanup_shadow(pam_handle_t *pamh, void *data,
+			   int error_status);
 
 #endif /* PAMMODUTIL_PRIVATE_H */
openSUSE Build Service is sponsored by