kevinlawler / kona

Open-source implementation of the K programming language
ISC License
1.36k stars 138 forks source link

global-buffer-overflow in kona #486

Closed gy741 closed 6 years ago

gy741 commented 6 years ago

Hello.

I found a global-buffer-overflow bug in kona.

Please confirm.

Thanks.

Steps to reproduce: 1.Compile the source code with ASan. 2.Execute the following command : ./k_test

=================================================================
==8342==ERROR: AddressSanitizer: global-buffer-overflow on address 0x0000006b9ddf at pc 0x000000552086 bp 0x7ffcad3b4990 sp 0x7ffcad3b4988
READ of size 1 at 0x0000006b9ddf thread T0
    #0 0x552085 in mark_adverb /home/karas/kona/src/p.c:212:12
    #1 0x552085 in wd_ /home/karas/kona/src/p.c:336
    #2 0x575cf4 in XN /home/karas/kona/src/k.c:54:14
    #3 0x575cf4 in X /home/karas/kona/src/k.c:50
    #4 0x6189a9 in tc /home/karas/kona/src/tests.c:40:9
    #5 0x65d51f in testsBook /home/karas/kona/src/tests.c:963:3
    #6 0x619293 in test /home/karas/kona/src/tests.c:68:3
    #7 0x5815d3 in kinit /home/karas/kona/src/kc.c:164:3
    #8 0x6185f1 in main /home/karas/kona/src/main.c:6:3
    #9 0x7f4e4e823c04 in __libc_start_main (/lib64/libc.so.6+0x21c04)
    #10 0x41bcab in _start (/home/karas/kona/k_test+0x41bcab)

0x0000006b9ddf is located 1 bytes to the left of global variable '<string literal>' defined in 'src/tests.c:963:3' (0x6b9de0) of size 10
  '<string literal>' is ascii string '+/1 2 3 4'
0x0000006b9ddf is located 37 bytes to the right of global variable '<string literal>' defined in 'src/tests.c:961:3' (0x6b9d80) of size 58
  '<string literal>' is ascii string 'A.I:1 2 3;A.F:2 5 7;B.F: 5 2 5 2 2 7 2 5 7 5; A.F ?/: B.F'
SUMMARY: AddressSanitizer: global-buffer-overflow /home/karas/kona/src/p.c:212:12 in mark_adverb
Shadow bytes around the buggy address:
  0x0000800cf360: f9 f9 f9 f9 00 05 f9 f9 f9 f9 f9 f9 00 06 f9 f9
  0x0000800cf370: f9 f9 f9 f9 00 06 f9 f9 f9 f9 f9 f9 00 00 00 05
  0x0000800cf380: f9 f9 f9 f9 05 f9 f9 f9 f9 f9 f9 f9 00 00 00 00
  0x0000800cf390: 00 00 00 01 f9 f9 f9 f9 00 04 f9 f9 f9 f9 f9 f9
  0x0000800cf3a0: 00 04 f9 f9 f9 f9 f9 f9 00 00 04 f9 f9 f9 f9 f9
=>0x0000800cf3b0: 00 00 00 00 00 00 00 02 f9 f9 f9[f9]00 02 f9 f9
  0x0000800cf3c0: f9 f9 f9 f9 03 f9 f9 f9 f9 f9 f9 f9 00 06 f9 f9
  0x0000800cf3d0: f9 f9 f9 f9 04 f9 f9 f9 f9 f9 f9 f9 00 00 03 f9
  0x0000800cf3e0: f9 f9 f9 f9 00 f9 f9 f9 f9 f9 f9 f9 00 00 05 f9
  0x0000800cf3f0: f9 f9 f9 f9 00 00 00 03 f9 f9 f9 f9 00 00 00 00
  0x0000800cf400: 00 06 f9 f9 f9 f9 f9 f9 00 01 f9 f9 f9 f9 f9 f9
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
==8342==ABORTING

========================================== [Acknowledgement] This work was supported by ICT R&D program of MSIP/IITP. [R7518-16-1001, Innovation hub for high Performance Computing]

tavmem commented 6 years ago

Status: Tried to replicate this issue in 2 separate environments. Both failed. This comment documents the attempt in OpenBSD-6.2 with clang

Modified a single line in Makefile

DEVFLAGS = -O0 -g3 -DDEBUG -fsanitize=address -Wall

Then executed gmake

$ gmake
cc -g -pthread -O3    -c -o src/0.o src/0.c
cc -g -pthread -O3    -c -o src/bswap.o src/bswap.c
cc -g -pthread -O3    -c -o src/c.o src/c.c
cc -g -pthread -O3    -c -o src/getline.o src/getline.c
cc -g -pthread -O3    -c -o src/mt.o src/mt.c
cc -g -pthread -O3    -c -o src/p.o src/p.c
cc -g -pthread -O3    -c -o src/r.o src/r.c
cc -g -pthread -O3    -c -o src/k.o src/k.c
cc -g -pthread -O3    -c -o src/kc.o src/kc.c
cc -g -pthread -O3    -c -o src/kx.o src/kx.c
cc -g -pthread -O3    -c -o src/kg.o src/kg.c
cc -g -pthread -O3    -c -o src/km.o src/km.c
cc -g -pthread -O3    -c -o src/kn.o src/kn.c
cc -g -pthread -O3    -c -o src/ko.o src/ko.c
cc -g -pthread -O3    -c -o src/ks.o src/ks.c
cc -g -pthread -O3    -c -o src/v.o src/v.c
cc -g -pthread -O3    -c -o src/va.o src/va.c
cc -g -pthread -O3    -c -o src/vc.o src/vc.c
cc -g -pthread -O3    -c -o src/vd.o src/vd.c
cc -g -pthread -O3    -c -o src/vf.o src/vf.c
cc -g -pthread -O3    -c -o src/vg.o src/vg.c
cc -g -pthread -O3    -c -o src/vq.o src/vq.c
cc -g -pthread -O3    -c -o src/main.o src/main.c
cc -g -pthread -O3  src/0.o src/bswap.o src/c.o src/getline.o src/mt.o src/p.o src/r.o src/k.o src/kc.o src/kx.o src/kg.o src/km.o src/kn.o src/ko.o src/ks.o src/v.o src/va.o src/vc.o src/vd.o src/vf.o src/vg.o src/vq.o src/main.o -o k -lm
src/v.o: In function `glueSS':
src/v.c:28: warning: warning: sprintf() is often misused, please use snprintf()
src/c.o: In function `filexist':
src/c.c:50: warning: warning: strcpy() is almost always misused, please use strlcpy()
src/c.o: In function `backslash_d':
src/c.c:465: warning: warning: strcat() is almost always misused, please use strlcat()
cc -g -pthread -O0 -g3 -DDEBUG -fsanitize=address -Wall -c  -o src/0.t.o src/0.c
cc: error: unsupported option '-fsanitize=address' for target 'amd64-unknown-openbsd6.2'
gmake: *** [Makefile:129: src/0.t.o] Error 1
tavmem commented 6 years ago

Status: In Fedora-27 with gcc. I made the same change to Makefile

DEVFLAGS = -O0 -g3 -DDEBUG -fsanitize=address -Wall

Then ran make

$ make
cc -g -pthread -O3    -c -o src/0.o src/0.c
cc -g -pthread -O3    -c -o src/bswap.o src/bswap.c
cc -g -pthread -O3    -c -o src/c.o src/c.c
cc -g -pthread -O3    -c -o src/getline.o src/getline.c
cc -g -pthread -O3    -c -o src/mt.o src/mt.c
cc -g -pthread -O3    -c -o src/p.o src/p.c
cc -g -pthread -O3    -c -o src/r.o src/r.c
cc -g -pthread -O3    -c -o src/k.o src/k.c
cc -g -pthread -O3    -c -o src/kc.o src/kc.c
cc -g -pthread -O3    -c -o src/kx.o src/kx.c
cc -g -pthread -O3    -c -o src/kg.o src/kg.c
cc -g -pthread -O3    -c -o src/km.o src/km.c
cc -g -pthread -O3    -c -o src/kn.o src/kn.c
cc -g -pthread -O3    -c -o src/ko.o src/ko.c
cc -g -pthread -O3    -c -o src/ks.o src/ks.c
cc -g -pthread -O3    -c -o src/v.o src/v.c
cc -g -pthread -O3    -c -o src/va.o src/va.c
cc -g -pthread -O3    -c -o src/vc.o src/vc.c
cc -g -pthread -O3    -c -o src/vd.o src/vd.c
cc -g -pthread -O3    -c -o src/vf.o src/vf.c
cc -g -pthread -O3    -c -o src/vg.o src/vg.c
cc -g -pthread -O3    -c -o src/vq.o src/vq.c
cc -g -pthread -O3    -c -o src/main.o src/main.c
cc -g -pthread -O3  src/0.o src/bswap.o src/c.o src/getline.o src/mt.o src/p.o src/r.o src/k.o src/kc.o src/kx.o src/kg.o src/km.o src/kn.o src/ko.o src/ks.o src/v.o src/va.o src/vc.o src/vd.o src/vf.o src/vg.o src/vq.o src/main.o -o k -lm -ldl
cc -g -pthread -O0 -g3 -DDEBUG -fsanitize=address -Wall -c  -o src/0.t.o src/0.c
cc -g -pthread -O0 -g3 -DDEBUG -fsanitize=address -Wall -c  -o src/bswap.t.o src/bswap.c
cc -g -pthread -O0 -g3 -DDEBUG -fsanitize=address -Wall -c  -o src/c.t.o src/c.c
cc -g -pthread -O0 -g3 -DDEBUG -fsanitize=address -Wall -c  -o src/getline.t.o src/getline.c
cc -g -pthread -O0 -g3 -DDEBUG -fsanitize=address -Wall -c  -o src/mt.t.o src/mt.c
cc -g -pthread -O0 -g3 -DDEBUG -fsanitize=address -Wall -c  -o src/p.t.o src/p.c
cc -g -pthread -O0 -g3 -DDEBUG -fsanitize=address -Wall -c  -o src/r.t.o src/r.c
cc -g -pthread -O0 -g3 -DDEBUG -fsanitize=address -Wall -c  -o src/k.t.o src/k.c
cc -g -pthread -O0 -g3 -DDEBUG -fsanitize=address -Wall -c  -o src/kc.t.o src/kc.c
cc -g -pthread -O0 -g3 -DDEBUG -fsanitize=address -Wall -c  -o src/kx.t.o src/kx.c
cc -g -pthread -O0 -g3 -DDEBUG -fsanitize=address -Wall -c  -o src/kg.t.o src/kg.c
cc -g -pthread -O0 -g3 -DDEBUG -fsanitize=address -Wall -c  -o src/km.t.o src/km.c
cc -g -pthread -O0 -g3 -DDEBUG -fsanitize=address -Wall -c  -o src/kn.t.o src/kn.c
cc -g -pthread -O0 -g3 -DDEBUG -fsanitize=address -Wall -c  -o src/ko.t.o src/ko.c
cc -g -pthread -O0 -g3 -DDEBUG -fsanitize=address -Wall -c  -o src/ks.t.o src/ks.c
cc -g -pthread -O0 -g3 -DDEBUG -fsanitize=address -Wall -c  -o src/v.t.o src/v.c
cc -g -pthread -O0 -g3 -DDEBUG -fsanitize=address -Wall -c  -o src/va.t.o src/va.c
cc -g -pthread -O0 -g3 -DDEBUG -fsanitize=address -Wall -c  -o src/vc.t.o src/vc.c
cc -g -pthread -O0 -g3 -DDEBUG -fsanitize=address -Wall -c  -o src/vd.t.o src/vd.c
cc -g -pthread -O0 -g3 -DDEBUG -fsanitize=address -Wall -c  -o src/vf.t.o src/vf.c
cc -g -pthread -O0 -g3 -DDEBUG -fsanitize=address -Wall -c  -o src/vg.t.o src/vg.c
cc -g -pthread -O0 -g3 -DDEBUG -fsanitize=address -Wall -c  -o src/vq.t.o src/vq.c
cc -g -pthread -O0 -g3 -DDEBUG -fsanitize=address -Wall -c  -o src/main.t.o src/main.c
cc -g -pthread -O0 -g3 -DDEBUG -fsanitize=address -Wall -c  -o src/tests.t.o src/tests.c
cc -g -pthread -O0 -g3 -DDEBUG -fsanitize=address -Wall src/0.t.o src/bswap.t.o src/c.t.o src/getline.t.o src/mt.t.o src/p.t.o src/r.t.o src/k.t.o src/kc.t.o src/kx.t.o src/kg.t.o src/km.t.o src/kn.t.o src/ko.t.o src/ks.t.o src/v.t.o src/va.t.o src/vc.t.o src/vd.t.o src/vf.t.o src/vg.t.o src/vq.t.o src/main.t.o src/tests.t.o -o k_test -lm -ldl
/usr/bin/ld: cannot find /usr/lib64/libasan.so.4.0.0
collect2: error: ld returned 1 exit status
make: *** [Makefile:108: k_test] Error 1

Planned next step: The Fedora/gcc result is a bit more descriptive. Will try to get /usr/lib64/libasan.so.4.0.0 installed.

tavmem commented 6 years ago

Status: was able to replicate global-buffer-overflow on Fedora/gcc:

$ sudo dnf install asan
Installed:
  libasan.x86_64 7.3.1-2.fc27                                                                                                                                                                                      
Complete!

$ make
cc -g -pthread -O0 -g3 -DDEBUG -fsanitize=address -Wall src/0.t.o src/bswap.t.o src/c.t.o src/getline.t.o src/mt.t.o src/p.t.o src/r.t.o src/k.t.o src/kc.t.o src/kx.t.o src/kg.t.o src/km.t.o src/kn.t.o src/ko.t.o src/ks.t.o src/v.t.o src/va.t.o src/vc.t.o src/vd.t.o src/vf.t.o src/vg.t.o src/vq.t.o src/main.t.o src/tests.t.o -o k_test -lm -ldl
$ ./k_test
t:0
=================================================================
==1601==ERROR: AddressSanitizer: global-buffer-overflow on address 0x0000004d16ff at pc 0x00000041afa2 bp 0x7ffe49455e40 sp 0x7ffe49455e30
READ of size 1 at 0x0000004d16ff thread T0
    #0 0x41afa1 in mark_adverb src/p.c:213
    #1 0x41d62b in wd_ src/p.c:337
    #2 0x41cfe8 in wd src/p.c:314
    #3 0x433256 in XN src/k.c:54
    #4 0x4331df in X src/k.c:50
    #5 0x48be9e in tc src/tests.c:40
    #6 0x4a6cbe in testsBook src/tests.c:965
    #7 0x48c4f1 in test src/tests.c:68
    #8 0x439b42 in kinit src/kc.c:164
    #9 0x48bb78 in main src/main.c:6
    #10 0x7f911744c009 in __libc_start_main (/lib64/libc.so.6+0x21009)
    #11 0x403349 in _start (/home/tom/konak/k_test+0x403349)

0x0000004d16ff is located 43 bytes to the right of global variable '*.LC984' defined in 'src/tests.c' (0x4d16c0) of size 20
  '*.LC984' is ascii string '1 0 1 0 0 2 0 1 2 1'
0x0000004d16ff is located 1 bytes to the left of global variable '*.LC985' defined in 'src/tests.c' (0x4d1700) of size 10
  '*.LC985' is ascii string '+/1 2 3 4'
SUMMARY: AddressSanitizer: global-buffer-overflow src/p.c:213 in mark_adverb
Shadow bytes around the buggy address:
  0x000080092280: 00 05 f9 f9 f9 f9 f9 f9 00 05 f9 f9 f9 f9 f9 f9
  0x000080092290: 00 06 f9 f9 f9 f9 f9 f9 00 06 f9 f9 f9 f9 f9 f9
  0x0000800922a0: 00 00 00 05 f9 f9 f9 f9 00 00 00 00 00 00 00 01
  0x0000800922b0: f9 f9 f9 f9 05 f9 f9 f9 f9 f9 f9 f9 00 04 f9 f9
  0x0000800922c0: f9 f9 f9 f9 00 04 f9 f9 f9 f9 f9 f9 00 00 00 00
=>0x0000800922d0: 00 00 00 02 f9 f9 f9 f9 00 00 04 f9 f9 f9 f9[f9]
  0x0000800922e0: 00 02 f9 f9 f9 f9 f9 f9 00 06 f9 f9 f9 f9 f9 f9
  0x0000800922f0: 03 f9 f9 f9 f9 f9 f9 f9 00 00 03 f9 f9 f9 f9 f9
  0x000080092300: 04 f9 f9 f9 f9 f9 f9 f9 00 00 05 f9 f9 f9 f9 f9
  0x000080092310: 00 f9 f9 f9 f9 f9 f9 f9 00 00 00 00 00 06 f9 f9
  0x000080092320: f9 f9 f9 f9 00 00 00 03 f9 f9 f9 f9 00 f9 f9 f9
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
==1601==ABORTING
$