xfree86: NUL-terminate strings in hwEnableIO
The Linux version of xf86EnableIO calls a helper function called hwEnableIO()
.
Except on Alpha, this function reads /proc/ioports looking for the 'keyboard'
and 'timer' ports, extracts the port ranges, and enables access to them. It does
this by reading 4 bytes from the string for the start port number and 4 bytes
for the last port number, passing those to atoi()
. However, it doesn't add a
fifth byte for a NUL terminator, so some implementations of atoi() read past the
end of this string, triggering an AddressSanitizer error:
==1383==ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7fff71fd5b74 at pc 0x7fe1be0de3e0 bp 0x7fff71fd5ae0 sp 0x7fff71fd5288
READ of size 5 at 0x7fff71fd5b74 thread T0
#0 0x7fe1be0de3df in __interceptor_atoi /build/gcc/src/gcc/libsanitizer/asan/asan_interceptors.cpp:520
#1 0x564971adcc45 in hwEnableIO ../hw/xfree86/os-support/linux/lnx_video.c:138
#2 0x564971adce87 in xf86EnableIO ../hw/xfree86/os-support/linux/lnx_video.c:174
#3 0x5649719f6a30 in InitOutput ../hw/xfree86/common/xf86Init.c:439
#4 0x564971585924 in dix_main ../dix/main.c:190
#5 0x564971b6246e in main ../dix/stubmain.c:34
#6 0x7fe1bdab6b24 in __libc_start_main (/usr/lib/libc.so.6+0x27b24)
#7 0x564971490e9d in _start (/home/aaron/git/x/xserver/build.asan/hw/xfree86/Xorg+0xb2e9d)
Address 0x7fff71fd5b74 is located in stack of thread T0 at offset 100 in frame
#0 0x564971adc96a in hwEnableIO ../hw/xfree86/os-support/linux/lnx_video.c:118
This frame has 3 object(s):
[32, 40) 'n' (line 120)
[64, 72) 'buf' (line 122)
[96, 100) 'target' (line 122) <== Memory access at offset 100 overflows this variable
HINT: this may be a false positive if your program uses some custom stack unwind mechanism, swapcontext or vfork
(longjmp and C++ exceptions *are* supported)
SUMMARY: AddressSanitizer: stack-buffer-overflow /build/gcc/src/gcc/libsanitizer/asan/asan_interceptors.cpp:520 in __interceptor_atoi
Shadow bytes around the buggy address:
0x10006e3f2b10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x10006e3f2b20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x10006e3f2b30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x10006e3f2b40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x10006e3f2b50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x10006e3f2b60: 00 00 f1 f1 f1 f1 00 f2 f2 f2 00 f2 f2 f2[04]f3
0x10006e3f2b70: f3 f3 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x10006e3f2b80: 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1
0x10006e3f2b90: f1 f1 f8 f2 00 f2 f2 f2 f8 f3 f3 f3 00 00 00 00
0x10006e3f2ba0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1
0x10006e3f2bb0: f1 f1 00 f3 f3 f3 00 00 00 00 00 00 00 00 00 00
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
==1383==ABORTING
Fix this by NUL-terminating the string.
Fixes: #1193 (comment 1053306) Signed-off-by: Aaron Plattner aplattner@nvidia.com