[PATCH]out of bounds read error in courier-authlib / userdb_get()

Hanno Böck <[email protected]>
Newsgroups gmane.mail.imap.courier.general
Message-ID <[email protected]>
Hi,

I found an out of bounds read bug in courier-authlib's userdb parser.

When compiling courier and courier-authlib with address sanitizer (-fsanitize=address) and configuring authentication with userdb, this causes an error on logins and the process terminates. I'll paste the error report below.

The bug is in the function userdb_get(), in this line:
https://github.com/svarshavchik/courier/blob/master/courier-authlib/userdb/userdb.c#L135

The relevant piece of code:
		if (memcmp(u, n, nl) == 0 &&

The memcmp compares u and n up to the length of n, but it is not
guaranteed that u is actually long enough. I believe this can easily be
fixed by replacing memcmp with strncmp, as u points to a
null-terminated string and strncmp guarantees that the comparison ends
with a null terminator.

I'm attaching a patch to fix this.


Address Sanitizer error:

==24432==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6040000001bb at pc 0x7f56373c0655 bp 0x7fff583a21f0 sp 0x7fff583a1998
READ of size 5 at 0x6040000001bb thread T0
    #0 0x7f56373c0654  (/usr/lib/gcc/x86_64-pc-linux-gnu/13/libasan.so.8+0xc7654)
    #1 0x7f56373c0aee in __interceptor_memcmp (/usr/lib/gcc/x86_64-pc-linux-gnu/13/libasan.so.8+0xc7aee)
    #2 0x7f56369959dd in userdb_get /var/tmp/portage/net-libs/courier-authlib-0.72.0-r1/work/courier-authlib-0.72.0/userdb/userdb.c:135
    #3 0x7f5636995d88 in userdb_gets /var/tmp/portage/net-libs/courier-authlib-0.72.0-r1/work/courier-authlib-0.72.0/userdb/userdb.c:181
    #4 0x7f563699616e in userdb_creates /var/tmp/portage/net-libs/courier-authlib-0.72.0-r1/work/courier-authlib-0.72.0/userdb/userdb.c:336
    #5 0x7f56369934c0 in auth_userdb_pre_common /var/tmp/portage/net-libs/courier-authlib-0.72.0-r1/work/courier-authlib-0.72.0/preauthuserdbcommon.c:47
    #6 0x7f5636992c66 in auth_userdb /var/tmp/portage/net-libs/courier-authlib-0.72.0-r1/work/courier-authlib-0.72.0/authuserdb.c:187
    #7 0x5559105dd988 in auth /var/tmp/portage/net-libs/courier-authlib-0.72.0-r1/work/courier-authlib-0.72.0/authdaemond.c:760
    #8 0x5559105dd988 in doauth /var/tmp/portage/net-libs/courier-authlib-0.72.0-r1/work/courier-authlib-0.72.0/authdaemond.c:865
    #9 0x5559105de6e7 in start /var/tmp/portage/net-libs/courier-authlib-0.72.0-r1/work/courier-authlib-0.72.0/authdaemond.c:1059
    #10 0x5559105da7c1 in main /var/tmp/portage/net-libs/courier-authlib-0.72.0-r1/work/courier-authlib-0.72.0/authdaemondcpp.cpp:29
    #11 0x7f5636d93f0b in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #12 0x7f5636d93fc4 in __libc_start_main_impl ../csu/libc-start.c:360
    #13 0x5559105da860 in _start (/usr/libexec/courier-authlib/authdaemond+0x4860)

0x6040000001bb is located 0 bytes after 43-byte region [0x604000000190,0x6040000001bb)
allocated by thread T0 here:
    #0 0x7f56373d4f3f in malloc (/usr/lib/gcc/x86_64-pc-linux-gnu/13/libasan.so.8+0xdbf3f)
    #1 0x7f56369957c8 in userdb /var/tmp/portage/net-libs/courier-authlib-0.72.0-r1/work/courier-authlib-0.72.0/userdb/userdb.c:114

SUMMARY: AddressSanitizer: heap-buffer-overflow (/usr/lib/gcc/x86_64-pc-linux-gnu/13/libasan.so.8+0xc7654) 
Shadow bytes around the buggy address:
  0x603fffffff00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x603fffffff80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x604000000000: fa fa fd fd fd fd fd fd fa fa 00 00 00 00 00 06
  0x604000000080: fa fa 00 00 00 00 00 06 fa fa 00 00 00 00 00 06
  0x604000000100: fa fa 00 00 00 00 00 06 fa fa fd fd fd fd fd fd
=>0x604000000180: fa fa 00 00 00 00 00[03]fa fa fa fa fa fa fa fa
  0x604000000200: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x604000000280: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x604000000300: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x604000000380: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x604000000400: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==24432==ABORTING

-- 
Hanno Böck
https://hboeck.de/

_______________________________________________
courier-users mailing list
[email protected]
Unsubscribe: https://lists.sourceforge.net/lists/listinfo/courier-users
courier-authlib-oob.diff (text/x-patch, 359 B)
diff -Naurp a/userdb/userdb.c b/userdb/userdb.c
--- a/userdb/userdb.c	2013-08-25 20:44:47.000000000 +0200
+++ b/userdb/userdb.c	2024-01-26 20:29:57.663207950 +0100
@@ -132,7 +132,7 @@ int	nl=strlen(n);
 
 	while (u && *u)
 	{
-		if (memcmp(u, n, nl) == 0 &&
+		if (strncmp(u, n, nl) == 0 &&
 			(u[nl] == 0 || u[nl] == '=' || u[nl] == '|'))
 		{
 			u += nl;
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.