Hi Stefan,

Thanks for r3esponding so quickly.

On 2013-12-04 11:56, Stefan Bühler wrote:
If the characters are not from this limited set, especially if the
first character is '$', then the Glibc crypt() expects '$' + id +
'$' + real-salt + '$'.
Glibc shouldn't require NUL-termination as long as there is a 3rd '$'.

I was concerned that if the stored password is malformed, crypt() could scan arbitrarily far away beyond the end of the string. Granted, a malicious user shouldn't ever be able to cause the stored password to be malformed.

The Glibc API limits real-salt to 16 bytes, and id is so far at most 2
bytes long, so the NUL-terminated salt should fit into 22 bytes (making
it 32 shouldn't hurt).

For what it's worth, I used the following patch before I came across your bug report. I guess the 256 is overkill considering your comments about the maximum salt size of 22.

If you or the maintainer feel that making a copy of the string is not worth it and would prefer to use your patch, I'm ok with that.

-kv
diff --git a/modules/pam_userdb/pam_userdb.c b/modules/pam_userdb/pam_userdb.c
index 37af682..04a17d6 100644
--- a/modules/pam_userdb/pam_userdb.c
+++ b/modules/pam_userdb/pam_userdb.c
@@ -214,15 +214,16 @@ user_lookup (pam_handle_t *pamh, const char *database, const char *cryptmode,
 	  /* crypt(3) password storage */
 
 	  char *cryptpw;
-	  char salt[2];
+	  char salt[256];
+	  int salt_len;
 
-	  if (data.dsize != 13) {
-	    compare = -2;
-	  } else if (ctrl & PAM_ICASE_ARG) {
+	  if (ctrl & PAM_ICASE_ARG) {
 	    compare = -2;
 	  } else {
-	    salt[0] = *data.dptr;
-	    salt[1] = *(data.dptr + 1);
+	    salt_len = sizeof(salt)-1;
+	    if (data.dsize < salt_len) salt_len = data.dsize;
+	    memcpy(salt, data.dptr, salt_len);
+	    salt[salt_len] = 0;
 
 	    cryptpw = crypt (pass, salt);
 

Reply via email to