oss-sec mailing list archives

memory safety bugs in bc


From: Hanno Böck <hanno () hboeck de>
Date: Wed, 28 Nov 2018 13:31:45 +0100

Hi,

bc is a command line calculator that is commonly available on Linux
systems.

I reported various memory safety bugs and crashes a long time ago, some
got also fixed but some more got ignored.

(I'm aware it's debatable whether a tool like bc should be considered
attack surface, as there are probably not many situations where it's fed
attacker controlled input.)


-----------------------------

echo 'define p(a[],u){}p(a[],0,0)'|./bc

Causes a heap out of bounds read, also segfaults without asan.

ASAN stack trace:

==2068==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6020000001e8 at pc 0x5593e5e43b32 bp 0x7fffa5908ed0 
sp 0x7fffa5908ec0
READ of size 8 at 0x6020000001e8 thread T0
    #0 0x5593e5e43b31 in process_params /mnt/ram/bc-1.07.1/bc/storage.c:1061
    #1 0x5593e5e39718 in execute /mnt/ram/bc-1.07.1/bc/execute.c:157
    #2 0x5593e5e44d26 in run_code /mnt/ram/bc-1.07.1/bc/util.c:295
    #3 0x5593e5e2df52 in yyparse ../../bc/bc.y:134
    #4 0x5593e5e2d0ea in main /mnt/ram/bc-1.07.1/bc/main.c:260
    #5 0x7f2b653a24ca in __libc_start_main (/lib64/libc.so.6+0x234ca)
    #6 0x5593e5e2c419 in _start (/mnt/ram/bc-1.07.1/bc/bc+0x9419)

0x6020000001e8 is located 8 bytes to the left of 16-byte region [0x6020000001f0,0x602000000200)
allocated by thread T0 here:
    #0 0x7f2b65636b10 in malloc (/usr/lib/gcc/x86_64-pc-linux-gnu/8.2.0/libasan.so.5+0xedb10)
    #1 0x5593e5e46ac2 in bc_malloc /mnt/ram/bc-1.07.1/bc/util.c:652
    #2 0x5593e5e43c01 in nextarg /mnt/ram/bc-1.07.1/bc/util.c:58
    #3 0x5593e5e3e83a in load_code /mnt/ram/bc-1.07.1/bc/load.c:261
    #4 0x5593e5e44bf6 in generate /mnt/ram/bc-1.07.1/bc/util.c:277
    #5 0x5593e5e2fed8 in yyparse ../../bc/bc.y:352
    #6 0x5593e5e2d0ea in main /mnt/ram/bc-1.07.1/bc/main.c:260
    #7 0x7f2b653a24ca in __libc_start_main (/lib64/libc.so.6+0x234ca)

-----------------------------

echo -e 'define a(s,t){if(0)0}for(s=0;;){j(a(),0)}\ns'|./bc

Causes a null pointer deref, also crashes without asan.

ASAN trace:
==2091==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x56201e2aafc8 bp 0x7fffb04d6d60 sp 
0x7fffb04d6d40 T0)
==2091==The signal is caused by a READ memory access.
==2091==Hint: address points to the zero page.
    #0 0x56201e2aafc7 in load_var /mnt/ram/bc-1.07.1/bc/storage.c:653
    #1 0x56201e2a37c7 in execute /mnt/ram/bc-1.07.1/bc/execute.c:324
    #2 0x56201e2add26 in run_code /mnt/ram/bc-1.07.1/bc/util.c:295
    #3 0x56201e296f52 in yyparse ../../bc/bc.y:134
    #4 0x56201e2960ea in main /mnt/ram/bc-1.07.1/bc/main.c:260
    #5 0x7fbdbe7124ca in __libc_start_main (/lib64/libc.so.6+0x234ca)
    #6 0x56201e295419 in _start (/mnt/ram/bc-1.07.1/bc/bc+0x9419)

-----------------------------

echo -e 'define t(x,y,d,s){f()}\ndefine f(){t()}\nfor(s=0;;){f()}\nfor(s=0;;){}' | ./bc

null pointer read, but doesn't crash without asan.

==6340==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x55fdb8a43d49 bp 0x7fffae7307e0 sp 
0x7fffae7307d0 T0)
==6340==The signal is caused by a READ memory access.
==6340==Hint: address points to the zero page.
    #0 0x55fdb8a43d48 in bc_free_num /mnt/ram/bc-1.07.1/lib/number.c:92
    #1 0x55fdb8a3d32a in store_var /mnt/ram/bc-1.07.1/bc/storage.c:461
    #2 0x55fdb8a368cf in execute /mnt/ram/bc-1.07.1/bc/execute.c:339
    #3 0x55fdb8a40d26 in run_code /mnt/ram/bc-1.07.1/bc/util.c:295
    #4 0x55fdb8a29f52 in yyparse ../../bc/bc.y:134
    #5 0x55fdb8a290ea in main /mnt/ram/bc-1.07.1/bc/main.c:260
    #6 0x7f763973b4ca in __libc_start_main (/lib64/libc.so.6+0x234ca)
    #7 0x55fdb8a28419 in _start (/mnt/ram/bc-1.07.1/bc/bc+0x9419)

-----------------------------

echo -e 'define t(x,y,d,s,t){if(0){}\nfor(;0<y;)f(0)}define f(x){(t())}for(s=0;;){t(0,1,0,0,0)}\nt()'|./bc

null pointer read, but doesn't crash without asan.

==6365==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x55d4e78cfd9c bp 0x7ffc83b7d590 sp 
0x7ffc83b7d560 T0)
==6365==The signal is caused by a READ memory access.
==6365==Hint: address points to the zero page.
    #0 0x55d4e78cfd9b in pop_vars /mnt/ram/bc-1.07.1/bc/storage.c:921
    #1 0x55d4e78c91e8 in execute /mnt/ram/bc-1.07.1/bc/execute.c:538
    #2 0x55d4e78d1d26 in run_code /mnt/ram/bc-1.07.1/bc/util.c:295
    #3 0x55d4e78baf52 in yyparse ../../bc/bc.y:134
    #4 0x55d4e78ba0ea in main /mnt/ram/bc-1.07.1/bc/main.c:260
    #5 0x7f9c3f6bb4ca in __libc_start_main (/lib64/libc.so.6+0x234ca)
    #6 0x55d4e78b9419 in _start (/mnt/ram/bc-1.07.1/bc/bc+0x9419)

-----------------------------

echo 'define m(x){for(;;)0}m(b[])'|./bc

null pointer read, but doesn't crash without asan.

==6373==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x7f7fd8cdaec2 bp 0x7ffd4d86c230 sp 
0x7ffd4d86b958 T0)
==6373==The signal is caused by a READ memory access.
==6373==Hint: address points to the zero page.
    #0 0x7f7fd8cdaec1  (/usr/lib/gcc/x86_64-pc-linux-gnu/8.2.0/libasan.so.5+0x108ec1)
    #1 0x7f7fd8c1f76c  (/usr/lib/gcc/x86_64-pc-linux-gnu/8.2.0/libasan.so.5+0x4d76c)
    #2 0x7f7fd8c200a4 in __interceptor_vfprintf (/usr/lib/gcc/x86_64-pc-linux-gnu/8.2.0/libasan.so.5+0x4e0a4)
    #3 0x561fe31fc5e6 in rt_error /mnt/ram/bc-1.07.1/bc/util.c:788
    #4 0x561fe31f8aed in process_params /mnt/ram/bc-1.07.1/bc/storage.c:1050
    #5 0x561fe31ee718 in execute /mnt/ram/bc-1.07.1/bc/execute.c:157
    #6 0x561fe31f9d26 in run_code /mnt/ram/bc-1.07.1/bc/util.c:295
    #7 0x561fe31e2f52 in yyparse ../../bc/bc.y:134
    #8 0x561fe31e20ea in main /mnt/ram/bc-1.07.1/bc/main.c:260
    #9 0x7f7fd8a2b4ca in __libc_start_main (/lib64/libc.so.6+0x234ca)
    #10 0x561fe31e1419 in _start (/mnt/ram/bc-1.07.1/bc/bc+0x9419)


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

mail/jabber: hanno () hboeck de
GPG: FE73757FA60E4E21B937579FA5880072BBB51E42


Current thread: