Heap buffer overflow on unit tests
I came across this when doing fuzz testing on a project that uses v_htmlescape and ran into a heap buffer overflow in this lib. Luckily its fairly easy to reproduce, one of the cases in the unit test triggers it. Having address sanitizer enabled makes it visible. Following is an example of invoke the tests to trigger the error:
stusmall@Stu-T470s:~/Workspace/Upstream/v_escape/v_htmlescape$ RUSTFLAGS="-Z sanitizer=address" cargo test --target x86_64-unknown-linux-gnu
Finished dev [unoptimized + debuginfo] target(s) in 0.04s
Running /home/stusmall/Workspace/Upstream/v_escape/target/x86_64-unknown-linux-gnu/debug/deps/v_htmlescape-71016b10e3478a4e
running 1 test
test test::test_escape ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Running /home/stusmall/Workspace/Upstream/v_escape/target/x86_64-unknown-linux-gnu/debug/deps/lib-3a65171842654aa5
running 1 test
=================================================================
==2726==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6030000019bf at pc 0x55a6ab2ef6d3 bp 0x7f5238bee9b0 sp 0x7f5238bee9a8
READ of size 32 at 0x6030000019bf thread T1 (test_escape)
#0 0x55a6ab2ef6d2 (/home/stusmall/Workspace/Upstream/v_escape/target/x86_64-unknown-linux-gnu/debug/deps/lib-3a65171842654aa5+0x1566d2)
#1 0x55a6ab2e98b9 (/home/stusmall/Workspace/Upstream/v_escape/target/x86_64-unknown-linux-gnu/debug/deps/lib-3a65171842654aa5+0x1508b9)
#2 0x55a6ab2d271d (/home/stusmall/Workspace/Upstream/v_escape/target/x86_64-unknown-linux-gnu/debug/deps/lib-3a65171842654aa5+0x13971d)
#3 0x55a6ab1d9006 (/home/stusmall/Workspace/Upstream/v_escape/target/x86_64-unknown-linux-gnu/debug/deps/lib-3a65171842654aa5+0x40006)
#4 0x55a6ab33856b (/home/stusmall/Workspace/Upstream/v_escape/target/x86_64-unknown-linux-gnu/debug/deps/lib-3a65171842654aa5+0x19f56b)
#5 0x55a6ab1cf698 (/home/stusmall/Workspace/Upstream/v_escape/target/x86_64-unknown-linux-gnu/debug/deps/lib-3a65171842654aa5+0x36698)
#6 0x55a6ab1d9415 (/home/stusmall/Workspace/Upstream/v_escape/target/x86_64-unknown-linux-gnu/debug/deps/lib-3a65171842654aa5+0x40415)
#7 0x55a6ab1bda48 (/home/stusmall/Workspace/Upstream/v_escape/target/x86_64-unknown-linux-gnu/debug/deps/lib-3a65171842654aa5+0x24a48)
#8 0x55a6ab1dc9f9 (/home/stusmall/Workspace/Upstream/v_escape/target/x86_64-unknown-linux-gnu/debug/deps/lib-3a65171842654aa5+0x439f9)
#9 0x55a6ab1cb904 (/home/stusmall/Workspace/Upstream/v_escape/target/x86_64-unknown-linux-gnu/debug/deps/lib-3a65171842654aa5+0x32904)
#10 0x55a6ab2a059e (/home/stusmall/Workspace/Upstream/v_escape/target/x86_64-unknown-linux-gnu/debug/deps/lib-3a65171842654aa5+0x10759e)
#11 0x55a6ab3270f9 (/home/stusmall/Workspace/Upstream/v_escape/target/x86_64-unknown-linux-gnu/debug/deps/lib-3a65171842654aa5+0x18e0f9)
#12 0x55a6ab2baf27 (/home/stusmall/Workspace/Upstream/v_escape/target/x86_64-unknown-linux-gnu/debug/deps/lib-3a65171842654aa5+0x121f27)
#13 0x55a6ab2958e4 (/home/stusmall/Workspace/Upstream/v_escape/target/x86_64-unknown-linux-gnu/debug/deps/lib-3a65171842654aa5+0xfc8e4)
#14 0x55a6ab299924 (/home/stusmall/Workspace/Upstream/v_escape/target/x86_64-unknown-linux-gnu/debug/deps/lib-3a65171842654aa5+0x100924)
#15 0x55a6ab3270f9 (/home/stusmall/Workspace/Upstream/v_escape/target/x86_64-unknown-linux-gnu/debug/deps/lib-3a65171842654aa5+0x18e0f9)
#16 0x55a6ab299fc1 (/home/stusmall/Workspace/Upstream/v_escape/target/x86_64-unknown-linux-gnu/debug/deps/lib-3a65171842654aa5+0x100fc1)
#17 0x55a6ab3183de (/home/stusmall/Workspace/Upstream/v_escape/target/x86_64-unknown-linux-gnu/debug/deps/lib-3a65171842654aa5+0x17f3de)
#18 0x55a6ab3264bf (/home/stusmall/Workspace/Upstream/v_escape/target/x86_64-unknown-linux-gnu/debug/deps/lib-3a65171842654aa5+0x18d4bf)
#19 0x7f523c5da163 (/lib/x86_64-linux-gnu/libpthread.so.0+0x8163)
#20 0x7f523c4e8dee (/lib/x86_64-linux-gnu/libc.so.6+0x11adee)
0x6030000019bf is located 15 bytes to the right of 32-byte region [0x603000001990,0x6030000019b0)
allocated by thread T1 (test_escape) here:
#0 0x55a6ab276943 (/home/stusmall/Workspace/Upstream/v_escape/target/x86_64-unknown-linux-gnu/debug/deps/lib-3a65171842654aa5+0xdd943)
#1 0x55a6ab3353c0 (/home/stusmall/Workspace/Upstream/v_escape/target/x86_64-unknown-linux-gnu/debug/deps/lib-3a65171842654aa5+0x19c3c0)
Thread T1 (test_escape) created by T0 here:
#0 0x55a6ab25f5cd (/home/stusmall/Workspace/Upstream/v_escape/target/x86_64-unknown-linux-gnu/debug/deps/lib-3a65171842654aa5+0xc65cd)
#1 0x55a6ab326151 (/home/stusmall/Workspace/Upstream/v_escape/target/x86_64-unknown-linux-gnu/debug/deps/lib-3a65171842654aa5+0x18d151)
SUMMARY: AddressSanitizer: heap-buffer-overflow (/home/stusmall/Workspace/Upstream/v_escape/target/x86_64-unknown-linux-gnu/debug/deps/lib-3a65171842654aa5+0x1566d2)
Shadow bytes around the buggy address:
0x0c067fff82e0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c067fff82f0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c067fff8300: fa fa fd fd fd fd fa fa fd fd fd fd fa fa 00 00
0x0c067fff8310: 00 00 fa fa 00 00 00 00 fa fa 00 00 00 00 fa fa
0x0c067fff8320: fd fd fd fa fa fa fd fd fd fa fa fa fd fd fd fd
=>0x0c067fff8330: fa fa 00 00 00 00 fa[fa]fd fd fd fd fa fa fa fa
0x0c067fff8340: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c067fff8350: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c067fff8360: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c067fff8370: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c067fff8380: 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
Shadow gap: cc
==2726==ABORTING
error: test failed, to rerun pass '--test lib'
stusmall@Stu-T470s:~/Workspace/Upstream/v_escape/v_htmlescape$ RUSTFLAGS="-Z sanitizer=address" cargo test --target x86_64-unknown-linux-gnu
Finished dev [unoptimized + debuginfo] target(s) in 0.04s
Running /home/stusmall/Workspace/Upstream/v_escape/target/x86_64-unknown-linux-gnu/debug/deps/v_htmlescape-71016b10e3478a4e
running 1 test
test test::test_escape ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Running /home/stusmall/Workspace/Upstream/v_escape/target/x86_64-unknown-linux-gnu/debug/deps/lib-3a65171842654aa5
running 1 test
=================================================================
==2726==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6030000019bf at pc 0x55a6ab2ef6d3 bp 0x7f5238bee9b0 sp 0x7f5238bee9a8
READ of size 32 at 0x6030000019bf thread T1 (test_escape)
#0 0x55a6ab2ef6d2 (/home/stusmall/Workspace/Upstream/v_escape/target/x86_64-unknown-linux-gnu/debug/deps/lib-3a65171842654aa5+0x1566d2)
#1 0x55a6ab2e98b9 (/home/stusmall/Workspace/Upstream/v_escape/target/x86_64-unknown-linux-gnu/debug/deps/lib-3a65171842654aa5+0x1508b9)
#2 0x55a6ab2d271d (/home/stusmall/Workspace/Upstream/v_escape/target/x86_64-unknown-linux-gnu/debug/deps/lib-3a65171842654aa5+0x13971d)
#3 0x55a6ab1d9006 (/home/stusmall/Workspace/Upstream/v_escape/target/x86_64-unknown-linux-gnu/debug/deps/lib-3a65171842654aa5+0x40006)
#4 0x55a6ab33856b (/home/stusmall/Workspace/Upstream/v_escape/target/x86_64-unknown-linux-gnu/debug/deps/lib-3a65171842654aa5+0x19f56b)
#5 0x55a6ab1cf698 (/home/stusmall/Workspace/Upstream/v_escape/target/x86_64-unknown-linux-gnu/debug/deps/lib-3a65171842654aa5+0x36698)
#6 0x55a6ab1d9415 (/home/stusmall/Workspace/Upstream/v_escape/target/x86_64-unknown-linux-gnu/debug/deps/lib-3a65171842654aa5+0x40415)
#7 0x55a6ab1bda48 (/home/stusmall/Workspace/Upstream/v_escape/target/x86_64-unknown-linux-gnu/debug/deps/lib-3a65171842654aa5+0x24a48)
#8 0x55a6ab1dc9f9 (/home/stusmall/Workspace/Upstream/v_escape/target/x86_64-unknown-linux-gnu/debug/deps/lib-3a65171842654aa5+0x439f9)
#9 0x55a6ab1cb904 (/home/stusmall/Workspace/Upstream/v_escape/target/x86_64-unknown-linux-gnu/debug/deps/lib-3a65171842654aa5+0x32904)
#10 0x55a6ab2a059e (/home/stusmall/Workspace/Upstream/v_escape/target/x86_64-unknown-linux-gnu/debug/deps/lib-3a65171842654aa5+0x10759e)
#11 0x55a6ab3270f9 (/home/stusmall/Workspace/Upstream/v_escape/target/x86_64-unknown-linux-gnu/debug/deps/lib-3a65171842654aa5+0x18e0f9)
#12 0x55a6ab2baf27 (/home/stusmall/Workspace/Upstream/v_escape/target/x86_64-unknown-linux-gnu/debug/deps/lib-3a65171842654aa5+0x121f27)
#13 0x55a6ab2958e4 (/home/stusmall/Workspace/Upstream/v_escape/target/x86_64-unknown-linux-gnu/debug/deps/lib-3a65171842654aa5+0xfc8e4)
#14 0x55a6ab299924 (/home/stusmall/Workspace/Upstream/v_escape/target/x86_64-unknown-linux-gnu/debug/deps/lib-3a65171842654aa5+0x100924)
#15 0x55a6ab3270f9 (/home/stusmall/Workspace/Upstream/v_escape/target/x86_64-unknown-linux-gnu/debug/deps/lib-3a65171842654aa5+0x18e0f9)
#16 0x55a6ab299fc1 (/home/stusmall/Workspace/Upstream/v_escape/target/x86_64-unknown-linux-gnu/debug/deps/lib-3a65171842654aa5+0x100fc1)
#17 0x55a6ab3183de (/home/stusmall/Workspace/Upstream/v_escape/target/x86_64-unknown-linux-gnu/debug/deps/lib-3a65171842654aa5+0x17f3de)
#18 0x55a6ab3264bf (/home/stusmall/Workspace/Upstream/v_escape/target/x86_64-unknown-linux-gnu/debug/deps/lib-3a65171842654aa5+0x18d4bf)
#19 0x7f523c5da163 (/lib/x86_64-linux-gnu/libpthread.so.0+0x8163)
#20 0x7f523c4e8dee (/lib/x86_64-linux-gnu/libc.so.6+0x11adee)
0x6030000019bf is located 15 bytes to the right of 32-byte region [0x603000001990,0x6030000019b0)
allocated by thread T1 (test_escape) here:
#0 0x55a6ab276943 (/home/stusmall/Workspace/Upstream/v_escape/target/x86_64-unknown-linux-gnu/debug/deps/lib-3a65171842654aa5+0xdd943)
#1 0x55a6ab3353c0 (/home/stusmall/Workspace/Upstream/v_escape/target/x86_64-unknown-linux-gnu/debug/deps/lib-3a65171842654aa5+0x19c3c0)
Thread T1 (test_escape) created by T0 here:
#0 0x55a6ab25f5cd (/home/stusmall/Workspace/Upstream/v_escape/target/x86_64-unknown-linux-gnu/debug/deps/lib-3a65171842654aa5+0xc65cd)
#1 0x55a6ab326151 (/home/stusmall/Workspace/Upstream/v_escape/target/x86_64-unknown-linux-gnu/debug/deps/lib-3a65171842654aa5+0x18d151)
SUMMARY: AddressSanitizer: heap-buffer-overflow (/home/stusmall/Workspace/Upstream/v_escape/target/x86_64-unknown-linux-gnu/debug/deps/lib-3a65171842654aa5+0x1566d2)
Shadow bytes around the buggy address:
0x0c067fff82e0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c067fff82f0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c067fff8300: fa fa fd fd fd fd fa fa fd fd fd fd fa fa 00 00
0x0c067fff8310: 00 00 fa fa 00 00 00 00 fa fa 00 00 00 00 fa fa
0x0c067fff8320: fd fd fd fa fa fa fd fd fd fa fa fa fd fd fd fd
=>0x0c067fff8330: fa fa 00 00 00 00 fa[fa]fd fd fd fd fa fa fa fa
0x0c067fff8340: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c067fff8350: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c067fff8360: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c067fff8370: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c067fff8380: 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
Shadow gap: cc
==2726==ABORTING
error: test failed, to rerun pass '--test lib'
Edited by Stuart Small