Blame SOURCES/passwd-0.79-no-length-limit-stdin-passwords.patch

821ffc
From ca46cac76757082322d19f736a88cbf81bd70063 Mon Sep 17 00:00:00 2001
821ffc
From: Miloslav Trmač <mitr@redhat.com>
821ffc
Date: Nov 02 2015 18:20:24 +0000
821ffc
Subject: Support passwords up to PAM_MAX_RESP_SIZE - 1 with --stdin
821ffc
821ffc
821ffc
---
821ffc
821ffc
diff --git a/passwd.c b/passwd.c
821ffc
index b1dd114..45acf02 100644
821ffc
--- a/passwd.c
821ffc
+++ b/passwd.c
821ffc
@@ -479,17 +479,32 @@ main(int argc, const char **argv)
821ffc
 	/* If we need to read the new password from stdin, read it and switch
821ffc
 	 * to the really-quiet stdin conversation function. */
821ffc
 	if (passwd_flags & PASSWD_STDIN) {
821ffc
-		char *ptr, newPassword[80];
821ffc
+		/* PAM's documentation says that PAM_MAX_RESP_SIZE is the
821ffc
+		 * maximum supported length of the password, but in practice
821ffc
+		 * the code (including examples in the OSF RFC) often truncates
821ffc
+		 * data at PAM_MAX_RESP_SIZE - 1. So, refuse to use anything
821ffc
+		 * longer than PAM_MAX_RESP_SIZE - 1, to prevent users from
821ffc
+		 * setting a password they won't be able to use to log in. */
821ffc
+		char *ptr, newPassword[PAM_MAX_RESP_SIZE];
821ffc
 		int i;
821ffc
 
821ffc
 		i = read(STDIN_FILENO, newPassword,
821ffc
-			 sizeof(newPassword) - 1);
821ffc
+			 sizeof(newPassword));
821ffc
 		if (i < 0) {
821ffc
 			fprintf(stderr,
821ffc
 				_("%s: error reading from stdin: %s\n"), progname,
821ffc
 				strerror(errno));
821ffc
 			exit(1);
821ffc
 		}
821ffc
+		if (i == sizeof(newPassword)) {
821ffc
+			if (newPassword[i - 1] != '\n') {
821ffc
+				fprintf(stderr,
821ffc
+					_("%s: password too long, maximum is %zu"),
821ffc
+					progname, sizeof(newPassword) - 1);
821ffc
+				exit(1);
821ffc
+			}
821ffc
+			i--;
821ffc
+		}
821ffc
 
821ffc
 		newPassword[i] = '\0';
821ffc
 		ptr = strchr(newPassword, '\n');
821ffc