crypt(3) - Paper over sizeof()/strlen() bug causing 32/64-bit issues
authorSamuel J. Greear <sjg@thesjg.com>
Fri, 20 Jan 2012 20:04:56 +0000 (13:04 -0700)
committerSamuel J. Greear <sjg@thesjg.com>
Fri, 20 Jan 2012 20:04:56 +0000 (13:04 -0700)
* In one place sizeof() was used instead of strlen(), causing the password
  to be muxed with 4 bytes of random stack data on 64-bit machines. Codify
  this behavior for reverse compatibility.

lib/libcrypt/deprecated-crypt-sha256.c
lib/libcrypt/deprecated-crypt-sha512.c

index d0a3dd3..be3b475 100644 (file)
 char*
 crypt_deprecated_sha256(const char *pw, const char *salt)
 {
-       static const char *magic = "$3$"; /* Magic string for this
-                                                                                * algorithm. Easier to change
-                                                                                * when factored as constant.
-                                                                                */
+        /*
+         * Magic constant (prefix) used to run over the password data.
+         *
+         * XXX:
+         *
+         * A bug below (sizeof instead of strlen) mandates the extra data after
+         * the closing $. This data is what just happened to be (consistently
+         * miraculously) on the stack following magic on 64-bit.
+         */
+       static const char *magic = "$3$";
+
        static char         passwd[120], *p;
        static const char *sp, *ep;
        unsigned char final[SHA256_SIZE];
@@ -77,7 +84,11 @@ crypt_deprecated_sha256(const char *pw, const char *salt)
        /* Hash in the password first. */
        SHA256_Update(&ctx, pw, strlen(pw));
        
-       /* Then the magic string */
+        /*
+         * Then the magic string
+         *
+         * XXX: sizeof instead of strlen, must retain
+         */
        SHA256_Update(&ctx, magic, sizeof(magic));
        
        /* Then the raw salt. */
index 3909761..b31da5e 100644 (file)
 char*
 crypt_deprecated_sha512(const char *pw, const char *salt)
 {
-       static const char *magic = "$4$"; /* Magic string for this
-                                                                                * algorithm. Easier to change
-                                                                                * when factored as constant.
-                                                                                */
+       /*
+        * Magic constant (prefix) used to run over the password data.
+        *
+        * XXX:
+        *
+        * A bug below (sizeof instead of strlen) mandates the extra data after
+        * the closing $. This data is what just happened to be (consistently
+        * miraculously) on the stack following magic on 64-bit.
+        */
+       static const char *magic = "$4$\0/etc";
+
        static char         passwd[120], *p;
        static const char *sp, *ep;
        unsigned char final[SHA512_SIZE];
@@ -77,7 +84,11 @@ crypt_deprecated_sha512(const char *pw, const char *salt)
        /* Hash in the password first. */
        SHA512_Update(&ctx, pw, strlen(pw));
        
-       /* Then the magic string */
+       /*
+        * Then the magic string
+        *
+        * XXX: sizeof instead of strlen, must retain
+        */
        SHA512_Update(&ctx, magic, sizeof(magic));
        
        /* Then the raw salt. */