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 [EMAIL PROTECTED]
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 ()); }