detail as:https://blog.csdn.net/suixin______/article/details/133713263
We meet some memory corruption issue in init process, source code at system/core/init. The corruption issue cause init crash and trigger kernel panic. It's hard to debug this kinds of issue via logs and dump, but we can enable ASAN in init process to detect the corruption issue.
Steps:
Merge debug patch to Android.bp:
- @@ -197,6 +197,17 @@ cc_binary {
- recovery_available: true,
- stem: "init",
- defaults: ["init_defaults"],
- + clang: true,
- + sanitize: {
- + address: true,
- + },
- + cflags: [
- + "-Wno-error",
- + "-fno-omit-frame-pointer",
- + "-O0",
- + "-Wno-frame-larger-than=",
- + "-fsanitize-recover=address" + ],
-
- - srcs: ["main.cpp"],
- + srcs: init_common_sources + ["main.cpp"],
Modify /init/service.cpp
- Result
Service::Start() { - post_data_ = ServiceList::GetInstance().IsPostData();
- LOG(INFO) << "starting service '" << name_ << "'...";
- + if(!GetProperty("test.debug.init.asan", "").empty()){
- + int *array = new int[100];
- + delete [] array;
- + LOG(INFO) << "asan detect";
- + LOG(INFO) << "array " << array[2];
- + } std::vector
descriptors; - for(const auto& socket : sockets_) {
- if (auto result = socket.Create(scon); result.ok()) {
Compile the project system/core/init. then do steps below:
After device bootup set debug property test.debug.init.asan by command:
adb shell setprop test.debug.init.asan test
Tips: on test version please don't set test.debug.init.asan, the property it's to trigger crash and verify ASAN work.
Try to trigger the debug code by shell command:
- ps -Af|grep cameraserver
- kill -9
If enable ASAN in init process success, ASAN will detect the debug code happen user after free issue, then init crash, device reboot and print logs like this:
- 02-16 04:46:36.067 0 0 I init : Service 'cameraserver' (pid 6417) received signal 9
- 02-16 04:46:36.067 0 0 I init : Sending signal 9 to service 'cameraserver' (pid 6417) process group...
- 02-16 04:46:36.068 0 0 I libprocessgroup: Successfully killed process cgroup uid 1047 pid 6417 in 0ms
- 02-16 04:46:36.081 0 0 I init : starting service 'cameraserver'...
- 02-16 04:46:36.081 0 0 I init : asan detect
- 02-16 04:46:36.074 1 1 I init : =================================================================
- 02-16 04:46:36.076 1 1 I init : ==1==ERROR: AddressSanitizer: heap-use-after-free on
Due to the way ASAN works, a library built with ASan cannot be used by an executable that's built without ASAN. In runtime situations where an ASAN library is loaded into an incorrect process, you will see unresolved symbol messages starting with:
_asan or _sanitizer
if use command below:
readelf -a [name] |grep asan
To enable ASAN and output lib into:
- /system/lib[64]/asan
- /vendor/lib[64]/asan
instead of:
- /system/lib[64]
- /vendor/lib[64]
Add the label LOCAL_MODULE_RELATIVE_PATH in the libs' Android.mk:
- LOCAL_CLANG := true
- LOCAL_SANITIZE := address
- LOCAL_MODULE_RELATIVE_PATH := asan
moreover, In Android.bp use:
relative_install_path: "asan";
lib with ASAN will output in /data/asan/system[vendor]/lib[64] and executable with ASAN will auto use /system/bin/linker_asan[64] to search the libs from the path /data/asan at first. If you get some runtime error, diable selinux by command 'adb shell setenforce 0', kill the process and try
again.
If adding LOCAL_MODULE_RELATIVE_PATH label, you need to add below in init.rc:
'setenv LD_LIBRARY_PATH'
Run your executable with: 'LD_LIBRARY_PATH=/system[vendor]/lib[64]/asan'.
e.g. mediaserver add the following to the appropriate section of /init.rc
or /init.$device$.rc or
- service media /system/bin/mediaserver
- class main
- user media
- group audio camera inet net_bt net_bt_admin net_bw_acct drmrpc mediadrm
- ioprio rt 4
- writepid /dev/cpuset/foreground/tasks
- setenv LD_LIBRARY_PATH /system/lib/asan
Warning: The LOCAL_MODULE_RELATIVE_PATH setting moves your library to /system[vendor]/lib[64]/asan, meaning that clobbering and rebuilding from scratch will result in the library missing from /system[vendor]/lib[64], and probably an unbootable image. That's an unfortunate limitation of the current build system. Don't clobber, before enable ASAN the project should be builded once, so that will keep default lib. Make sure two libs been generated one as default use by other executable without ASAN, and the other one used by the executable with ASAN.
reading:
/proc/$PID/maps
If it's not, you may need to check SELinux, like :
- $ adb root
- $ adb shell setenforce 0
then restart the process with adb shell kill $PID
ASAN cannot detect corruption into Java code. But it can detect bugs in the JNI libraries. For that, you'll need to build zygote which in this case is /system/bin/app_process(32|64) with ASAN. This will enable ASAN in all apps & system_server on the device at the same time. Here is an example steps to enable ASAN in zygote, shared lib libart.so and libhwui.so:
in order to make sure default shared lib libart.so & libart.so in /system/lib[64].
- LOCAL_MODULE_STEM_32 := app_process32
- LOCAL_MODULE_STEM_64 := app_process64
- LOCAL_CFLAGS += $(app_process_cflags)
- +LOCAL_CLANG := true
- +LOCAL_SANITIZE := address
- +LOCAL_CFLAGS += -Wno-error
- #Disable compiler optimization
- +LOCAL_CFLAGS += -O0
- #For these flags Please refer to section FAQ
- +LOCAL_CFLAGS += -Wno-frame-larger-than=
- +LOCAL_CFLAGS += -fsanitize-recover=address
- +LOCAL_CFLAGS += -fno-omit-frame-pointer
- Android N, Android.mk
- diff --git a/build/Android.common_build.mk b/build/Android.common_build.mk
- index 2294ddb..f4ebe20 100644
- --- a/build/Android.common_build.mk
- +++ b/build/Android.common_build.mk
- @@ -221,7 +221,6 @@ art_cflags := \
- -std=gnu++11 \
- -ggdb3 \
- -Wall \
- - -Werror \
- -Wextra \
- -Wstrict-aliasing \
- -fstrict-aliasing \
- diff --git a/dalvikvm/Android.mk b/dalvikvm/Android.mk
- index 71e9a28..ff2fa5a 100644
- --- a/dalvikvm/Android.mk
- +++ b/dalvikvm/Android.mk
- @@ -18,7 +18,7 @@ LOCAL_PATH := $(call my-dir)
- include art/build/Android.common.mk
- -dalvikvm_cflags := -Wall -Werror -Wextra -std=gnu++11
- +dalvikvm_cflags := -Wall -Wextra -std=gnu++11
- include $(CLEAR_VARS)
- LOCAL_MODULE := dalvikvm
- diff --git a/runtime/Android.mk b/runtime/Android.mk
- index aa12c83..563305e 100644
- --- a/runtime/Android.mk
- +++ b/runtime/Android.mk
- @@ -527,6 +527,9 @@ endif
- LOCAL_C_INCLUDES += art/cmdline
- LOCAL_C_INCLUDES += art/sigchainlib
- LOCAL_C_INCLUDES += art
- + LOCAL_SANITIZE := address
- + LOCAL_MULTILIB := both
- + LOCAL_MODULE_RELATIVE_PATH := asan
- ifeq ($$(art_static_or_shared),static)
- LOCAL_STATIC_LIBRARIES := libnativehelper
- Android O/P, Android.bp
- diff --git a/runtime/Android.bp b/runtime/Android.bp
- index dd9cc03..d96cca5 100644
- --- a/runtime/Android.bp
- +++ b/runtime/Android.bp
- @@ -276,6 +276,17 @@ cc_defaults {
- "arch/arm/thread_arm.cc",
- "arch/arm/fault_handler_arm.cc",
- ],
- + clang: true,
- + sanitize: {
- + address: true,
- + },
- + cflags: ["-Wno-frame-larger-than=",
- + "-fno-omit-frame-pointer",
- + "-O0",
- + "-fsanitize-recover=address",
- + ],
- },
- arm64: {
- srcs: [
- @@ -290,6 +301,17 @@ cc_defaults {
- "monitor_pool.cc",
- "arch/arm64/fault_handler_arm64.cc",
- ],
- + clang: true,
- + sanitize: {
- + address: true,
- + },
- + cflags: ["-Wno-frame-larger-than=",
- + "-fno-omit-frame-pointer",
- + "-O0",
- + "-fno-sanitize-address-use-after-scope",
- + "-fsanitize-recover=address",
- + ],
- },
- cc_defaults {
- name: "libhwui_defaults",
- defaults: ["hwui_defaults"],
- + cflags: [
- + "-Wno-error",
- + "-fno-omit-frame-pointer",
- + "-O0",
- + "-Wno-frame-larger-than=",
- + "-fsanitize-recover=address"
- + ],
- + clang: true,
- + sanitize: {
- + address: true,
- + },
- + relative_install_path: "asan",
- diff --git a/rootdir/init.environ.rc.in b/rootdir/init.environ.rc.in
- index 32817fa..2f349fb 100644
- --- a/rootdir/init.environ.rc.in
- +++ b/rootdir/init.environ.rc.in
- @@ -4,6 +4,7 @@ on init
- export ANDROID_ROOT /system
- export ANDROID_ASSETS /system/app
- export ANDROID_DATA /data
- + export ASAN_OPTIONS halt_on_error=0
- export ANDROID_STORAGE /storage
- export EXTERNAL_STORAGE /sdcard
- export ASEC_MOUNTPOINT /mnt/asec
- diff --git a/rootdir/init.zygote64_32.rc b/rootdir/init.zygote64_32.rc
- index a422fcc..f3391c1 100644
- --- a/rootdir/init.zygote64_32.rc
- +++ b/rootdir/init.zygote64_32.rc
- @@ -1,5 +1,8 @@
- service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server --socket-name=zygote
- class main
- + setenv LD_LIBRARY_PATH /system/lib64/asan:/system/lib64:/system/vendor/lib64:/system/lib
- + setenv ASAN_OPTIONS halt_on_error=0:allow_user_segv_handler=true
- socket zygote stream 660 root system
- onrestart write /sys/android_power/request_state wake
- onrestart write /sys/power/state on
- @@ -11,6 +14,9 @@ service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-s
- service zygote_secondary /system/bin/app_process32 -Xzygote /system/bin --zygote --socket-name=zygote_secondary
- class main
- + setenv LD_LIBRARY_PATH /system/lib/asan:/system/lib:/system/vendor/lib
- + setenv ASAN_OPTIONS halt_on_error=0
- + allow_user_segv_handler=true
- socket zygote_secondary stream 660 root system
- onrestart restart zygote
- writepid /dev/cpuset/foreground/tasks
In mentioned scenario ASAN is enabled for libart.so, libhwui.so & zygote. We can enable ASAN for other shared libraries using similar approach.
Yes it can, AddressSanitizer has recently got continue-after-error mode. This is somewhat experimental so may not yet be as reliable as default setting (and not as timely supported). Also keep
in mind that errors after the first one may actually be spurious. To enable continue-after-error, compile with:
-fsanitize-recover=address
and then run your code with:
ASAN_OPTIONS=halt_on_error=0
Modify file "./external/compiler-rt/lib/asan/Android.mk" as following:
- 178 #ifeq (true,$(FORCE_BUILD_SANITIZER_SHARED_OBJECTS))
- 179 #ifdef 2ND_ADDRESS_SANITIZER_RUNTIME_LIBRARY
- 180 $(eval $(call build-asan-rt-shared-library,$(ADDRESS_SANITIZER_RUNTIME_LIBRARY)
- ,64))
- 181 $(eval $(call build-asan-rt-shared-library,$(
- 2ND_ADDRESS_SANITIZER_RUNTIME_LIBRARY),32))
- 182 #else
- 183 # $(eval $(call build-asan-rt-shared-library,$(ADDRESS_SANITIZER_RUNTIME_LIBRARY),32))
- 184 #endif
- 185 #endif
And then build comiler-rt:
- $cd /external/compiler-rt/
- $ mm
After you build it successfully, you can find libclang_rt.asan-arm-android.so and libclang_rt.asan-aarch64-android.so under the path:
/system/lib64/
copy them to the path:
/external/compiler-rt/lib/asan/scripts/
Modify the script '/external/compiler-rt/lib/asan/scripts/asan_device_setup'. Change the line :
(LD_PRELOAD=\$LD_PRELOAD:$_asan_rt \\
as:
LD_PRELOAD=$_asan_rt \\
Then connect your device to your Linux PC and execute this script, If the script run success the device will reboot automatically.
Issue happend on android N. On O & P its been generated auto.
Logs:
- ninja: error: 'out/target/product/xxxx/system/bin/linker_asan64', needed by 'out/target/product/
- xxxx/system/bin/asan_test', missing and no known rule to make it
- make: *** [ninja_wrapper] Error 1
- make: Leaving directory `/mnt/android/Builds/xxxx'
Solution: copy linker to linker_asan(32 bit & 64 bit)
- cp out/target/product/xxx/system/bin/linker64 out/target/product/xxx/system/bin/linker_asan64
- cp out/target/product/xxx/system/bin/linker out/target/product/xxx/system/bin/linker_asan
Logs:
- art/runtime/class_linker.cc:351:19: error: stack frame size of 3040 bytes in function 'art::
- ClassLinker::InitWithoutImage' [ -Werror,-Wframe-larger-than= ]
- bool ClassLinker::InitWithoutImage(std::vector
> - boot_class_path,
- ^ art/runtime/class_linker.cc:1559:19: error: stack frame size of 1824 bytes in function '
- art::
- ClassLinker::AddImageSpace' [-Werror,-Wframe-larger-than=]
Solution:
Add LOCAL_CFLAGS "-Werror" and "-Wno-frame-larger-than=" in Android.mk.
- diff --git a/runtime/Android.mk b/runtime/Android.mk
- index aa12c83..e2e3075 100644--- a/runtime/Android.mk
- +++ b/runtime/Android.mk
- @@ -523,6 +523,13 @@ endif
- LOCAL_MULTILIB := both
- endif
- + LOCAL_CLANG := true
- + LOCAL_SANITIZE := address
- + LOCAL_MULTILIB := both
- ++
- LOCAL_CFLAGS += -Werror
- + LOCAL_CFLAGS += -Wno-frame-larger-than=
- +
- LOCAL_C_INCLUDES += $$(ART_C_INCLUDES)
- LOCAL_C_INCLUDES += art/cmdline
- LOCAL_C_INCLUDES += art/sigchainlib
he problem occur on Android O, In android P incldue the patch. Logs:
- 03-28 01:59:00.239 1912 1912 I : ==1912==Shadow memory range interleaves with an
- existing memory mapping. ASan cannot proceed correctly. ABORTING.
- 03-28 01:59:00.239 1912 1912 I :
- 03-28 01:59:00.239 1912 1912 I : ==1912==ASan shadow was supposed to be located in the
- [0x00000000-0x1fffffff] range.
- 03-28 01:59:00.239 1912 1912 I :
- 03-28 01:59:00.249 1912 1912 I : ==1912==Process memory map follows:
- 03-28 01:59:00.249 1912 1912 I :
- 03-28 01:59:00.249 1912 1912 I : 0x0ed56000-0x0ed5d000 /system/bin/app_process32
- 03-28 01:59:00.249 1912 1912 I :
- 03-28 01:59:00.249 1912 1912 I : 0x0ed5d000-0x0ed5e000 /system/bin/app_process32
merge below kernel patch. Rebuild and reflash boot.img”:
- Change-Id: Iceaba90a3745323288be01f73aa51f4f4dbbda16
- ---
- arch/arm64/include/asm/elf.h | 12 ++++++------
- 1 file changed, 6 insertions(+), 6 deletions(-)diff --git a/arch/arm64/include/asm/elf.h b/arch/arm64/include/asm/elf.h
- index b983322..a383c28 100644
- --- a/arch/arm64/include/asm/elf.h
- +++ b/arch/arm64/include/asm/elf.h
- @@ -114,11 +114,12 @@
- #define ELF_EXEC_PAGESIZE PAGE_SIZE
- /*
- - * This is the base location for PIE (ET_DYN with INTERP) loads. On
- - * 64-bit, this is raised to 4GB to leave the entire 32-bit address
- - * space open for things that want to use the area for 32-bit pointers.
- + * This is the location that an ET_DYN program is loaded if exec'ed. Typical
- + * use of this is to invoke "./ld.so someprog" to test out a new version of
- + * the loader. We need to make sure that it is out of the way of the program
- + * that it will "exec", and that there is sufficient room for the brk.
- */
- -#define ELF_ET_DYN_BASE 0x100000000UL
- +#define ELF_ET_DYN_BASE (2 * TASK_SIZE_64 / 3)
- #ifndef __ASSEMBLY__
- @@ -169,8 +170,7 @@ extern int arch_setup_additional_pages(struct linux_binprm *bprm,
- #ifdef CONFIG_COMPAT
- -/* PIE load location for compat arm. Must match ARM ELF_ET_DYN_BASE. */
- -#define COMPAT_ELF_ET_DYN_BASE 0x000400000UL
- +#define COMPAT_ELF_ET_DYN_BASE (2 * TASK_SIZE_32 / 3)
- /* AArch32 registers. */
- #define COMPAT_ELF_NGREG 18
Try to compile your code with:
-fno-omit-frame-pointer
or set:
ASAN_OPTIONS=fast_unwind_on_malloc=0
the latter would be a performance killer though unless you also specify malloc_context_size=2 or lower. Note that frame-pointer-based unwinding does not work on Thumb.
disable compiler optimization by add cflags
LOCAL_CFLAGS += -O0
To get a reasonable performance add -O1 or higher.
- int main(int argc, char **argv) {
- int *array = new int[100];
- delete [] array;
- return array[argc]; // BOOM
- }
clang -O -g -fsanitize=address %t && ./a.out
- =================================================================
- ==6254== ERROR: AddressSanitizer: heap-use-after-free on address 0x603e0001fc64 at pc 0x417f6a bp 0x7fff626b3250 sp 0x7fff626b3248
- READ of size 4 at 0x603e0001fc64 thread T0
- #0 0x417f69 in main example_UseAfterFree.cc:5
- #1 0x7fae62b5076c (/lib/x86_64-linux-gnu/libc.so.6+0x2176c)
- #2 0x417e54 (a.out+0x417e54)
- 0x603e0001fc64 is located 4 bytes inside of 400-byte region [0x603e0001fc60,0x603e0001fdf0)
- freed by thread T0 here:
- #0 0x40d4d2 in operator delete[](void*) /home/kcc/llvm/projects/compiler-rt/lib/asan/asan_new_delete.cc:61
- #1 0x417f2e in main example_UseAfterFree.cc:4
- previously allocated by thread T0 here:
- #0 0x40d312 in operator new[](unsigned long) /home/kcc/llvm/projects/compiler-rt/lib/asan/asan_new_delete.cc:46
- #1 0x417f1e in main example_UseAfterFree.cc:3
- Shadow bytes around the buggy address:
- 0x1c07c0003f30: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
- 0x1c07c0003f40: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
- 0x1c07c0003f50: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
- 0x1c07c0003f60: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
- 0x1c07c0003f70: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
- =>0x1c07c0003f80: fa fa fa fa fa fa fa fa fa fa fa fa[fd]fd fd fd
- 0x1c07c0003f90: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
- 0x1c07c0003fa0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
- 0x1c07c0003fb0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fa fa
- 0x1c07c0003fc0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
- 0x1c07c0003fd0: 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
- Heap righ redzone: fb
- Freed Heap region: fd
- Stack left redzone: f1
- Stack mid redzone: f2
- Stack right redzone: f3
- Stack partial redzone: f4
- Stack after return: f5
- Stack use after scope: f8
- Global redzone: f9
- Global init order: f6
- Poisoned by user: f7
- ASan internal: fe
- int main(int argc, char **argv) {
- int *array = new int[100];
- array[0] = 0;
- int res = array[argc + 100]; // BOOM
- delete [] array;
- return res;
- }
- =================================================================
- ==6226== ERROR: AddressSanitizer: heap-buffer-overflow on address 0x603e0001fdf4 at pc 0x417f8c bp 0x7fff64c0c010 sp 0x7fff64c0c008
- READ of size 4 at 0x603e0001fdf4 thread T0
- #0 0x417f8b in main example_HeapOutOfBounds.cc:5
- #1 0x7fa97c09376c (/lib/x86_64-linux-gnu/libc.so.6+0x2176c)
- #2 0x417e54 (a.out+0x417e54)
- 0x603e0001fdf4 is located 4 bytes to the right of 400-byte region [0x603e0001fc60,0x603e0001fdf0)
- allocated by thread T0 here:
- #0 0x40d312 in operator new[](unsigned long) /home/kcc/llvm/projects/compiler-rt/lib/asan/asan_new_delete.cc:46
- #1 0x417f1c in main example_HeapOutOfBounds.cc:3
- Shadow bytes around the buggy address:
- 0x1c07c0003f60: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
- 0x1c07c0003f70: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
- 0x1c07c0003f80: fa fa fa fa fa fa fa fa fa fa fa fa 00 00 00 00
- 0x1c07c0003f90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 0x1c07c0003fa0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- =>0x1c07c0003fb0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00[fa]fa
- 0x1c07c0003fc0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
- 0x1c07c0003fd0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
- 0x1c07c0003fe0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
- 0x1c07c0003ff0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
- 0x1c07c0004000: 00 00 00 00 00 00 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
- Heap righ redzone: fb
- Freed Heap region: fd
- Stack left redzone: f1
- Stack mid redzone: f2
- Stack right redzone: f3
- Stack partial redzone: f4
- Stack after return: f5
- Stack use after scope: f8
- Global redzone: f9
- Global init order: f6
- Poisoned by user: f7
- ASan internal: fe
- ==6226== ABORTING
- int main(int argc, char **argv) {
- int stack_array[100];
- stack_array[1] = 0;
- return stack_array[argc + 100]; // BOOM
- }
- =================================================================
- ==6240== ERROR: AddressSanitizer: stack-buffer-overflow on address 0x7fff8098b2b4 at pc 0x417fe1 bp 0x7fff8098b0f0 sp 0x7fff8098b0e8
- READ of size 4 at 0x7fff8098b2b4 thread T0
- #0 0x417fe0 in main example_StackOutOfBounds.cc:5
- #1 0x7fa3667c976c (/lib/x86_64-linux-gnu/libc.so.6+0x2176c)
- #2 0x417e54 (a.out+0x417e54)
- Address 0x7fff8098b2b4 is located at offset 436 in frame
of T0's stack: - This frame has 1 object(s):
- [32, 432) 'stack_array'
- HINT: this may be a false positive if your program uses some custom stack unwind mechanism or swapcontext
- (longjmp and C++ exceptions *are* supported)
- Shadow bytes around the buggy address:
- 0x1ffff0131600: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 0x1ffff0131610: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 0x1ffff0131620: f1 f1 f1 f1 00 00 00 00 00 00 00 00 00 00 00 00
- 0x1ffff0131630: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 0x1ffff0131640: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- =>0x1ffff0131650: 00 00 00 00 00 00[f4]f4 f3 f3 f3 f3 00 00 00 00
- 0x1ffff0131660: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 0x1ffff0131670: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 0x1ffff0131680: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 0x1ffff0131690: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 0x1ffff01316a0: 00 00 00 00 00 00 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
- Heap righ redzone: fb
- Freed Heap region: fd
- Stack left redzone: f1
- Stack mid redzone: f2
- Stack right redzone: f3
- Stack partial redzone: f4
- Stack after return: f5
- Stack use after scope: f8
- Global redzone: f9
- Global init order: f6
- Poisoned by user: f7
- ASan internal: fe
- ==6240== ABORTING
- int global_array[100] = {-1};
- int main(int argc, char **argv) {
- return global_array[argc + 100]; // BOOM
- }
- =================================================================
- ==6211== ERROR: AddressSanitizer: global-buffer-overflow on address 0x000000622314 at pc 0x417fee bp 0x7fff2e146300 sp 0x7fff2e1462f8
- READ of size 4 at 0x000000622314 thread T0
- #0 0x417fed in main example_GlobalOutOfBounds.cc:4
- #1 0x7f1c10d2a76c (/lib/x86_64-linux-gnu/libc.so.6+0x2176c)
- #2 0x417ef4 (a.out+0x417ef4)
- 0x000000622314 is located 4 bytes to the right of global variable 'global_array (example_GlobalOutOfBounds.cc)' (0x622180) of size 400
- Shadow bytes around the buggy address:
- 0x1000000c4410: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 0x1000000c4420: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 0x1000000c4430: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 0x1000000c4440: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 0x1000000c4450: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- =>0x1000000c4460: 00 00[f9]f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9 f9
- 0x1000000c4470: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 0x1000000c4480: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 0x1000000c4490: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 0x1000000c44a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 0x1000000c44b0: 00 00 00 00 00 00 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
- Heap righ redzone: fb
- Freed Heap region: fd
- Stack left redzone: f1
- Stack mid redzone: f2
- Stack right redzone: f3
- Stack partial redzone: f4
- Stack after return: f5
- Stack use after scope: f8
- Global redzone: f9
- Global init order: f6
- Poisoned by user: f7
- ASan internal: fe
- ==6211== ABORTING
- // RUN: clang -O -g -fsanitize=address %t && ./a.out
- // By default, AddressSanitizer does not try to detect
- // stack-use-after-return bugs.
- // It may still find such bugs occasionally
- // and report them as a hard-to-explain stack-buffer-overflow.
- // You need to run the test with ASAN_OPTIONS=detect_stack_use_after_return=1
-
- int *ptr;
- __attribute__((noinline))
- void FunctionThatEscapesLocalObject() {
- int local[100];
- ptr = &local[0];
- }
-
- int main(int argc, char **argv) {
- FunctionThatEscapesLocalObject();
- return ptr[argc];
- }
- =================================================================
- ==6268== ERROR: AddressSanitizer: stack-use-after-return on address 0x7fa19a8fc024 at pc 0x4180d5 bp 0x7fff73c3fc50 sp 0x7fff73c3fc48
- READ of size 4 at 0x7fa19a8fc024 thread T0
- #0 0x4180d4 in main example_UseAfterReturn.cc:17
- #1 0x7fa19b11d76c (/lib/x86_64-linux-gnu/libc.so.6+0x2176c)
- #2 0x417f34 (a.out+0x417f34)
- Address 0x7fa19a8fc024 is located at offset 36 in frame <_Z30FunctionThatEscapesLocalObjectv> of T0's stack:
- This frame has 1 object(s):
- [32, 432) 'local'
- HINT: this may be a false positive if your program uses some custom stack unwind mechanism or swapcontext
- (longjmp and C++ exceptions *are* supported)
- Shadow bytes around the buggy address:
- 0x1ff43351f7b0: fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe
- 0x1ff43351f7c0: fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe
- 0x1ff43351f7d0: fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe
- 0x1ff43351f7e0: fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe
- 0x1ff43351f7f0: fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe fe
- =>0x1ff43351f800: f5 f5 f5 f5[f5]f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5
- 0x1ff43351f810: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5
- 0x1ff43351f820: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5
- 0x1ff43351f830: f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 f5 00 00 00 00
- 0x1ff43351f840: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 0x1ff43351f850: 00 00 00 00 00 00 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
- Heap righ redzone: fb
- Freed Heap region: fd
- Stack left redzone: f1
- Stack mid redzone: f2
- Stack right redzone: f3
- Stack partial redzone: f4
- Stack after return: f5
- Stack use after scope: f8
- Global redzone: f9
- Global init order: f6
- Poisoned by user: f7
- ASan internal: fe
- ==6268== ABORTING
13.6 Use after scope:
- // RUN: clang -O -g -fsanitize=address -fsanitize-address-use-after-scope \
- // use-after-scope.cpp -o /tmp/use-after-scope
- // RUN: /tmp/use-after-scope
- // Check can be disabled in run-time:
- // RUN: ASAN_OPTIONS=detect_stack_use_after_scope=0 /tmp/use-after-scope
-
- volatile int *p = 0;
- int main() {
- {
- int x = 0;
- p = &x;
- }
- *p = 5;
- return 0;
- }
- =================================================================
- ==58237==ERROR: AddressSanitizer: stack-use-after-scope on address 0x7ffc4d830880 at pc 0x0000005097ed bp 0x7ffc4d830850 sp 0x7ffc4d830848
- WRITE of size 4 at 0x7ffc4d830880 thread T0
- #0 0x5097ec (/tmp/use-after-scope+0x5097ec)
- #1 0x7ff85fa6bf44 (/lib/x86_64-linux-gnu/libc.so.6+0x21f44)
- #2 0x41a005 (/tmp/use-after-scope+0x41a005)
- Address 0x7ffc4d830880 is located in stack of thread T0 at offset 32 in frame
- #0 0x5096ef (/tmp/use-after-scope+0x5096ef)
- This frame has 1 object(s):
- [32, 36) 'x' <== Memory access at offset 32 is inside this variable
- HINT: this may be a false positive if your program uses some custom stack unwind mechanism or swapcontext
- (longjmp and C++ exceptions *are* supported)
- SUMMARY: AddressSanitizer: stack-use-after-scope (/tmp/use-after-scope+0x5097ec)
- Shadow bytes around the buggy address:
- 0x100009afe0c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 0x100009afe0d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 0x100009afe0e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 0x100009afe0f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 0x100009afe100: 00 00 00 00 00 00 00 00 00 00 00 00 f1 f1 f1 f1
- =>0x100009afe110:[f8]f3 f3 f3 00 00 00 00 00 00 00 00 00 00 00 00
- 0x100009afe120: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 0x100009afe130: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 0x100009afe140: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 0x100009afe150: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
- 0x100009afe160: 00 00 00 00 00 00 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
- Heap right redzone: fb
- Freed heap region: fd
- Stack left redzone: f1
- Stack mid redzone: f2
- Stack right redzone: f3
- Stack partial redzone: f4
- 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
- ==58237==ABORTING