2014.zeronights.ru

Download Report

Transcript 2014.zeronights.ru

Kernel AddressSanitizer
A fast memory error detector
for Linux kernel
Dmitry Vyukov, dvyukov@
Nov 14, 2014, ZeroNights
Google Confidential and Proprietary
Address/Thread/MemorySanitizer
AddressSanitizer (ASan): use-after-free, use-after-return, out-ofbounds on heap, stack, globals.
ThreadSanitizer (TSan): data races, deadlocks, mallocs in signal
handlers.
MemorySanitizer (MSan): uses of uninitialized memory
[Valgrind is sloooooooooooow]
Google Confidential and Proprietary
User-space usage
●
●
●
●
●
Continuous testing of Chromium and server-side codebase.
We use "asanified" Chrome as default browser.
ClusterFuzz: massive Chromium fuzzing.
End-to-end system tests and live traffic serving.
Lots of internal fuzzing.
Thousands of bugs found.
Also found bugs in: Firefox, Opera, vlc, ffmpeg, FreeType, WebRTC,
MySQL, PostgreSQL, perl, PHP, clang, gcc, glibc.
Google Confidential and Proprietary
Linux Kernel
CONFIG_DEBUG_SLAB: does not detect OOB reads, best-effort UAF
detection.
CONFIG_DEBUG_PAGEALLOC: Detects UAF only when the whole
page is unused.
CONFIG_KMEMCHECK: Slow.
Google Confidential and Proprietary
Kernel AddressSanitizer
CONFIG_KASAN: fast and comprehensive solution for UAF and OOB.
● Based on compiler instrumentation (fast)
● OOB for both writes and reads
● OOB for globals and stack
● Strong UAF detection
● Prompt detection of bad memory accesses
● Informative reports
Google Confidential and Proprietary
Shadow byte
Every aligned 8-byte word of memory has only 9 states:
first k bytes (0<=k<=8) are addressable, the rest are not.
State of every 8-byte word can be encoded in 1 byte
(shadow byte)
(Extreme: up to 128 application bytes per 1 shadow byte)
Google Confidential and Proprietary
Instrumentation: 8-byte access
*ptr = ...
char *shadow = AddrToShadow(ptr);
if (*shadow)
ReportError(ptr);
*ptr = ...
Google Confidential and Proprietary
Shadow Memory Mapping
shadow = (addr>>3) + offset
Google Confidential and Proprietary
Instrumentation Example
MOV
%RDI, %RAX
copy address
SHR
$0x3, %RAX
divide by 8
MOV
0xFFFFD90000000000, %RCX
CMPB $0x0, (%RAX, %RCX)
load&test shadow
JNE
fail
# report failure
MOVQ $0x1234, (%RDI)
store
#
#
# load offset
#
# original
Google Confidential and Proprietary
Run-time Support
● Map shadow memory during bootstrap
● SLAB/SLUB integration:
o
o
o
add redzones
poison/unpoison
delay reuse (quarantine)
● Error reporting
Google Confidential and Proprietary
Trophies
● ~20 bugs in upstream kernel
● ~20 in our internal kernel
● X bugs found by Samsung and Oracle
Google Confidential and Proprietary
Example Report: UAF
ERROR: AddressSanitizer: heap-use-after-free on address ffff880064d11924
ffff880064d11924 is located 84 bytes inside of 104-byte region [ffff880064d118d0,
ffff880064d11938)
Accessed by thread T3916:
#1 ffffffff813fbb30 (ext4_mb_release_context+0x70/0xa40) ./fs/ext4/mballoc.c:4269
#2 ffffffff81401888 (ext4_mb_new_blocks+0x888/0x9b0) ./fs/ext4/mballoc.c:4432
#3 ffffffff813f2594 (ext4_ext_map_blocks+0x1404/0x1ba0) ./fs/ext4/extents.c:4213
Freed by thread T14794:
#1 ffffffff813f7832 (ext4_mb_pa_callback+0x32/0x40) ./fs/ext4/mballoc.c:3428
#2
inlined
rcu_do_batch ./kernel/rcutree.c:1991
#3
inlined
invoke_rcu_callbacks ./kernel/rcutree.c:2229
Allocated by thread T1087:
#1 ffffffff8190e928 (ext4_mb_new_inode_pa+0xd8/0x752) ./fs/ext4/mballoc.c:3506
#2 ffffffff8140190b (ext4_mb_new_blocks+0x90b/0x9b0) ./fs/ext4/mballoc.c:4417
#3 ffffffff813f2594 (ext4_ext_map_blocks+0x1404/0x1ba0) ./fs/ext4/extents.c:4213.
Shadow bytes around the buggy address:
ffff880064d11900: fd fd fd fd[fd]fd fd fa fa fa fa fa fa fa fa fa
Google Confidential and Proprietary
Example Report: OOB
AddressSanitizer: heap-buffer-overflow on address ffff8800521e8730
ffff8800521e8730 is located 16 bytes to the left of 512-byte region [ffff8800521e8740,
ffff8800521e8940)
Accessed by thread T11464:
#1 ffffffffa0003b1c (ip6_finish_output2+0x54c/0x840 [ipv6])
#2 ffffffffa00088dc (ip6_fragment+0xe2c/0x1520 [ipv6])
#3 ffffffffa00090f7 (ip6_finish_output+0x127/0x190 [ipv6])
#4 ffffffffa00091e1 (ip6_output+0x81/0x140 [ipv6])
#5 ffffffffa000630c (ip6_local_out+0x4c/0x60 [ipv6])
Allocated by thread T11464:
#1 ffffffff817e0201 (__alloc_skb+0x91/0x280)
#2 ffffffff817d807a (sock_wmalloc+0x6a/0xe0)
#3 ffffffffa0005ea6 (ip6_append_data+0x1906/0x1c20 [ipv6])
#4 ffffffffa0030dd7 (rawv6_sendmsg+0x6a7/0x15c0 [ipv6])
#5 ffffffff818bb498 (inet_sendmsg+0x108/0x160)
Shadow bytes around the buggy address:
ffff8800521e8700: fa fa fa fa fa fa[fa]fa 00 00 00 00 00 00 00 00
"I guess the following patch might be worth a CVE"
Google Confidential and Proprietary
Thanks!
http://address-sanitizer.googlecode.com
http://github.com/google/kasan
Questions?
Dmitry Vyukov, Google
dvyukov@
Google Confidential and Proprietary