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