[Date Prev][Date Next] [Chronological] [Thread] [Top]

(ITS#7851) [PATCH] buffer overrun in password checkers with malformed hash

Full_Name: Ryan Tandy
Version: master, commit 141f1680
OS: Ubuntu 14.04
URL: ftp://ftp.openldap.org/incoming/rtandy_20140511_fix-passwd-b64-buffer.patch
Submission from: (NULL) (

The password checkers call lutil_b64_pton like this:

rc = lutil_b64_pton(passwd->bv_val, orig_pass, passwd->bv_len);

However, the size of orig_pass is actually only 3/4 of passwd->bv_len.

Normally this isn't a problem; however, if the length of the password hash is
not a multiple of 4, then LUTIL_BASE64_DECODE_LEN rounds down, orig_pass gets a
shorter buffer allocated than is actually needed, and it's possible for
lutil_b64_pton to write past its end.

(How can that happen? An admin could mess up copy-pasting from slappasswd to
userPassword/olcRootPW, as could a user with write access to their own
userPassword who decided to set it manually.)


$ slappasswd -s secret -h '{SSHA}' 

If we lose the last character ('e') and try to authenticate against the length
31 string, clang's AddressSanitizer notices:

==15335==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x603000049736
at pc 0xef0720 bp 0x7fa9b38d1c10 sp 0x7fa9b38d1c08
WRITE of size 1 at 0x603000049736 thread T2
    #0 0xef071f in lutil_b64_pton (libraries/liblutil/base64.c:225)
    #1 0xe9547c in chk_ssha1 (libraries/liblutil/passwd.c:508)
    #2 0xe90a09 in lutil_passwd (libraries/liblutil/passwd.c:327)
    #3 0x7d5e1c in slap_passwd_check (servers/slapd/passwd.c:529)
[snip ...]
0x603000049736 is located 0 bytes to the right of 22-byte region
allocated by thread T2 here:
    #0 0x43c9a4 in malloc (/opt/openldap/libexec/slapd+0x43c9a4)
    #1 0x112903f in ber_memalloc_x (libraries/liblber/memory.c:228)
    #2 0x1129396 in ber_memalloc (libraries/liblber/memory.c:244)
    #3 0xe952ea in chk_ssha1 (libraries/liblutil/passwd.c:503)
    #4 0xe90a09 in lutil_passwd (libraries/liblutil/passwd.c:327)
    #5 0x7d5e1c in slap_passwd_check (servers/slapd/passwd.c:529)

(Built with ./configure CC=clang CFLAGS="-O0 -g -fsanitize=address")

Patch in URL. (Apparently the apr1 passwd module has CRLF endings; sorry for the
noisy diff.)

BTW, I noticed in the same routines that orig_pass is allocated with + 1 to the
required length, as if it were to be null-terminated, but that's never done. Is
that intentional? (AFAICS ber_memalloc doesn't zero memory, maybe I'm wrong.)