On Wed, Aug 08, 2018 at 02:45:29PM +0100, Ricardo Mestre wrote:
> Hi,
> 
> When openssl(1) passwd is invoked without passing in the `password' as 
> argument
> , meaning interactively, and if the password is 10 or more characters it will
> show the following memory corruption error, and using -crypt which is the
> default:
> 
> openssl(43025) in free(): chunck canary corrupted 0x13a8dc4a1bb0 0xa@0xa
> 
> pw_len is set to 8, then passwd_malloc_size is set to pw_len + 2 in order to 
> be
> able to warn the user that the password will be truncated then it calls
> EVP_read_pw_string(3) which allocates the space size of the input buffer, in
> this case password_malloc_size plus 1 for the NUL-termination character 
> through
> strlcpy(3).
> 
> When we finally call free(password_malloc) the sizes will differ and the 
> memory
> will be corrupted, in order to solve this when we allocate memory for the 
> input
> buffer we need to add plus 1 for the NUL-termination character.
> 
> Comments? OK?

Nice find. I think this is an off-by-one in EVP_read_pw_string_min()'s
usage of UI_add_input_string() (and UI_add_verify_string()). The man
page explicitly says that NUL is *not* counted in minlen and maxlen.

     UI_add_input_string() and UI_add_verify_string() add a prompt to ui, as
     well as flags and a result buffer and the desired minimum and maximum
     sizes of the result, not counting the final NUL character.

Notice that EVP_read_pw_string(buf, sizeof buf, ...) is a common enough
idiom.  All these are subject to a similar buffer overrun.  On the other
hand, everywhere else our tree has the correct usage of

        UI_add_input_string(ui, prompt, flags, buf, 0, sizeof(buf) - 1),

so I believe we should fix this in EVP_read_pw_string_min() as follows:

Index: evp/evp_key.c
===================================================================
RCS file: /var/cvs/src/lib/libcrypto/evp/evp_key.c,v
retrieving revision 1.24
diff -u -p -r1.24 evp_key.c
--- evp/evp_key.c       29 Jan 2017 17:49:23 -0000      1.24
+++ evp/evp_key.c       8 Aug 2018 15:23:32 -0000
@@ -107,11 +107,11 @@ EVP_read_pw_string_min(char *buf, int mi
        if (ui == NULL)
                return -1;
        if (UI_add_input_string(ui, prompt, 0, buf, min,
-           (len >= BUFSIZ) ? BUFSIZ - 1 : len) < 0)
+           (len >= BUFSIZ) ? BUFSIZ - 1 : len - 1) < 0)
                return -1;
        if (verify) {
                if (UI_add_verify_string(ui, prompt, 0, buff, min,
-                   (len >= BUFSIZ) ? BUFSIZ - 1 : len, buf) < 0)
+                   (len >= BUFSIZ) ? BUFSIZ - 1 : len - 1, buf) < 0)
                        return -1;
        }
        ret = UI_process(ui);

Reply via email to