[Pkg-shadow-devel] Bug#377825: passwd: chpasswd/chgpasswd break if compiled with SSP

Colin Watson cjwatson at debian.org
Tue Jul 11 13:27:36 UTC 2006


Package: passwd
Version: 1:4.0.16-2
Severity: normal

When chpasswd or chgpasswd are compiled with SSP (the -fstack-protector
option in gcc 4.1), and you attempt to use the -m option with either of
them, they crash on exit from main() with "stack smashing detected".
This turns out to be due to an overflow of the 'salt' array.

The attached patch fixes this by making sure the salt returned from
crypt_make_salt is properly truncated if MD5_CRYPT_ENAB is disabled, and
by making chpasswd and chgpasswd more careful to avoid a buffer overflow
while handling that salt in their MD5 modes. I believe that either
change alone would fix the bug, but I made both changes just to be
absolutely sure.

Thanks,

-- 
Colin Watson                                       [cjwatson at debian.org]
-------------- next part --------------
Index: shadow-4.0.16/libmisc/salt.c
===================================================================
--- shadow-4.0.16.orig/libmisc/salt.c	2006-07-11 12:52:27.000000000 +0100
+++ shadow-4.0.16/libmisc/salt.c	2006-07-11 12:54:20.000000000 +0100
@@ -24,11 +24,13 @@
 {
 	struct timeval tv;
 	static char result[40];
+	int max_salt_len = 8;
 
 	result[0] = '\0';
 #ifndef USE_PAM
 	if (getdef_bool ("MD5_CRYPT_ENAB")) {
 		strcpy (result, "$1$");	/* magic for the new MD5 crypt() */
+		max_salt_len += 3;
 	}
 #endif
 
@@ -39,8 +41,8 @@
 	strcat (result, l64a (tv.tv_usec));
 	strcat (result, l64a (tv.tv_sec + getpid () + clock ()));
 
-	if (strlen (result) > 3 + 8)	/* magic+salt */
-		result[11] = '\0';
+	if (strlen (result) > max_salt_len)
+		result[max_salt_len] = '\0';
 
 	return result;
 }
Index: shadow-4.0.16/src/chgpasswd.c
===================================================================
--- shadow-4.0.16.orig/src/chgpasswd.c	2006-07-11 13:17:08.000000000 +0100
+++ shadow-4.0.16/src/chgpasswd.c	2006-07-11 13:18:08.000000000 +0100
@@ -243,10 +243,16 @@
 		newpwd = cp;
 		if (!eflg) {
 			if (md5flg) {
-				char salt[12] = "$1$";
+				char md5salt[12] = "$1$";
+				char *salt = crypt_make_salt ();
 
-				strcat (salt, crypt_make_salt ());
-				cp = pw_encrypt (newpwd, salt);
+				if (strncmp (salt, "$1$", 3) == 0) {
+					strncat (md5salt, salt, 11);
+				} else {
+					strcat (md5salt, "$1$");
+					strncat (md5salt, salt, 8);
+				}
+				cp = pw_encrypt (newpwd, md5salt);
 			} else
 				cp = pw_encrypt (newpwd, crypt_make_salt ());
 		}
Index: shadow-4.0.16/src/chpasswd.c
===================================================================
--- shadow-4.0.16.orig/src/chpasswd.c	2006-07-11 12:54:25.000000000 +0100
+++ shadow-4.0.16/src/chpasswd.c	2006-07-11 13:17:00.000000000 +0100
@@ -238,10 +238,16 @@
 		newpwd = cp;
 		if (!eflg) {
 			if (md5flg) {
-				char salt[12] = "$1$";
+				char md5salt[12] = "";
+				char *salt = crypt_make_salt ();
 
-				strcat (salt, crypt_make_salt ());
-				cp = pw_encrypt (newpwd, salt);
+				if (strncmp (salt, "$1$", 3) == 0) {
+					strncat (md5salt, salt, 11);
+				} else {
+					strcat (md5salt, "$1$");
+					strncat (md5salt, salt, 8);
+				}
+				cp = pw_encrypt (newpwd, md5salt);
 			} else
 				cp = pw_encrypt (newpwd, crypt_make_salt ());
 		}


More information about the Pkg-shadow-devel mailing list