This patch moves recv and recvfrom interceptors to sanitizer_common to enable them in ASan. This those, we would be able to catch CVE-2015-7547 with dynamic stack buffer overflow (https://groups.google.com/forum/#!topic/address-sanitizer/ttPxNhTK9TU).
Details
Diff Detail
- Repository
- rL LLVM
Event Timeline
I think this should go into sanitizer_common, to also cover tsan.
(msan has one, so merge msan's one into sanitizer_common).
also, would be nice to have a test in test/asan/TestCases/Linux
OK, let's try more. Moved recvfrom and recv interceptors from TSan and MSan to sanitizer_common. I'm adding Dmitry to reviewers because this change affects TSan. The testcase for ASan may look scary at first glance, but actually it's quite simple:
- Create simple UDP server in thread 1 and wait for a message. The size of allocated destination buffer is less then expected message length.
- Create simple UDP client in thread 0 and send the message.
- Crash in recvfrom function due to buffer overflow.
lib/sanitizer_common/sanitizer_common_interceptors.inc | ||
---|---|---|
5352 | this is copied from recv, needs to be updated | |
5354 | this var is unused | |
5357 | res > 0 | |
5359 | this is different from what msan did | |
5361 | drop this |
lib/sanitizer_common/sanitizer_common_interceptors.inc | ||
---|---|---|
5359 | You are right. This is msan specific code, so perhaps we could wrap the whole if to macro (say, COMMON_INTERCEPTOR_UNPOISON_COND) and define it like this: #define COMMON_INTERCEPTOR_UNPOISON_COND(srcaddr, sz, srcaddr_sz) \ do { \ if (srcaddr) { \ SIZE_T sz = *addrlen; \ __msan_unpoison(srcaddr, Min(sz, srcaddr_sz)); \ } \ } while (false) for msan and empty macros for others (just like COMMON_INTERCEPTOR_UNPOISON_PARAM)? |
lib/sanitizer_common/sanitizer_common_interceptors.inc | ||
---|---|---|
5359 | __msan_unpoison(srcaddr, Min(sz, *addrlen)) looks simpler to me |
Otherwise looks good.
lib/sanitizer_common/sanitizer_common_interceptors.inc | ||
---|---|---|
5360 | I would just do: if (srcaddr) __msan_unpoison(srcaddr, Min(srcaddr_sz, *addrlen)); The macro makes code more convoluted without adding significant value. Every time I read this function I will need to go and check macro definition. |
lib/sanitizer_common/sanitizer_common_interceptors.inc | ||
---|---|---|
5360 |
Agree here, but wouldn't this lead to use of undeclared identifier '__msan_unpoison' errors in {a, t}san_interceptors.cc? I used the macro just to avoid such issues. Perhaps I can avoid introducing a new macro and write something like this: if (srcaddr) COMMON_INTERCEPTOR_INITIALIZE_RANGE(srcaddr, Min(srcaddr_sz, (SIZE_T)*addrlen)); |
lib/sanitizer_common/sanitizer_common_interceptors.inc | ||
---|---|---|
5360 | Right. |
I've also disabled recvfrom.cc testcase (http://reviews.llvm.org/rL261870) for now due to buildbot failure:
FAIL: AddressSanitizer-i386-linux :: TestCases/Linux/recvfrom.cc (524 of 1166) ******************** TEST 'AddressSanitizer-i386-linux :: TestCases/Linux/recvfrom.cc' FAILED ******************** Script: -- /mnt/b/sanitizer-buildbot1/sanitizer-x86_64-linux/build/clang_build/./bin/clang --driver-mode=g++ -fsanitize=address -mno-omit-leaf-frame-pointer -fno-omit-frame-pointer -fno-optimize-sibling-calls -gline-tables-only -m32 /mnt/b/sanitizer-buildbot1/sanitizer-x86_64-linux/build/llvm/projects/compiler-rt/test/asan/TestCases/Linux/recvfrom.cc -o /mnt/b/sanitizer-buildbot1/sanitizer-x86_64-linux/build/clang_build/projects/compiler-rt/test/asan/I386LinuxConfig/TestCases/Linux/Output/recvfrom.cc.tmp && not /mnt/b/sanitizer-buildbot1/sanitizer-x86_64-linux/build/clang_build/projects/compiler-rt/test/asan/I386LinuxConfig/TestCases/Linux/Output/recvfrom.cc.tmp 2>&1 | FileCheck /mnt/b/sanitizer-buildbot1/sanitizer-x86_64-linux/build/llvm/projects/compiler-rt/test/asan/TestCases/Linux/recvfrom.cc -- Exit Code: 2 Command Output (stderr): -- FileCheck error: '-' is empty. --
compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc | ||
---|---|---|
5343 ↗ | (On Diff #49020) | I think you can submit such an obvious fix directly. |
compiler-rt/trunk/lib/sanitizer_common/sanitizer_common_interceptors.inc | ||
---|---|---|
5343 ↗ | (On Diff #49020) | Thanks, I've already done it (approved by Dmitry): http://reviews.llvm.org/D17608. |
this is copied from recv, needs to be updated