Note on Android AddressSanitizer build bringup

/ Android

Android build system supports SANITIZE_TARGET environment variable to choose sanitizer option for all modules at once. However, some of Rust library is not considered to work with this global sanitizer option because Rust library is not following ASAN automatic path modification. In addition, EGL Loader is also not automatically following ASAN path modification. This article memorize manual modification for fixing it.

Problems to solve

Basically ASAN enabled library can only work with ASAN enable program. To manage ASAN enabled libaries on the target board, ASAN enabled libraries will be installed on different location /data/asan as part of debugging facilities. This way only ASAN enabled program can refer /data/asan and usual program can still work with normal path. Linker will be in charge of this path selection at program execution and mostly it works by just setting SANITIZE_TARGET=address. However, Rust based executable/library is out side out this consideration. If global ASAN option is enabled, non-ASAN libraries is missing on usual path but Rust executable/library is still expecting basic .so to be placed on usual path. As another problem, if program have hard coded library path and it doesn't consider global ASAN option, it will encounter the same library missing problem. EGL loader is such example.

Conclusion

Here is concluded changes to minimally bring up Android with SANITIZE_TARGET=address.

1. build/soong paths

Edit build/soong/android/paths.go as follows:

diff --git a/android/paths.go b/android/paths.go
index 7ab1f22..4270566 100644
--- a/android/paths.go
+++ b/android/paths.go
@@ -2184,7 +2184,7 @@ func modulePartition(ctx ModuleInstallPathContext, device bool) string {
                        partition = "system"
                }
                if ctx.InstallInSanitizerDir() {
-                       partition = "data/asan/" + partition
+                       partition = "" + partition
                }
        }
        return partition

2. EGL Loader fix

Edit frameworks/native/opengl/libs/EGL/Loader.cpp as follows:

diff --git a/opengl/libs/EGL/Loader.cpp b/opengl/libs/EGL/Loader.cpp
index 7012df21ae..40119389f5 100644
--- a/opengl/libs/EGL/Loader.cpp
+++ b/opengl/libs/EGL/Loader.cpp
@@ -76,9 +76,9 @@ static const char* HAL_SUBNAME_KEY_PROPERTIES[3] = {

 static const char* const VENDOR_LIB_EGL_DIR =
 #if defined(__LP64__)
-        "/vendor/lib64/egl";
+        "/data/asan/vendor/lib64/egl";
 #else
-        "/vendor/lib/egl";
+        "/data/asan/vendor/lib/egl";
 #endif

 static const char* const SYSTEM_LIB_DIR =

3. ASAN_OPTIONS fix

Edit system/core/rootdir/Android.bp as follows:

diff --git a/rootdir/Android.bp b/rootdir/Android.bp
index 44acbba..3f6a120 100644
--- a/rootdir/Android.bp
+++ b/rootdir/Android.bp
@@ -141,7 +141,7 @@ sanitizer_libraries_txt {
 }

 EXPORT_GLOBAL_ASAN_OPTIONS = select(soong_config_variable("ANDROID", "ASAN_ENABLED"), {
-    true: "export ASAN_OPTIONS include=/system/asan.options",
+    true: "export ASAN_OPTIONS include=/system/etc/asan.options",
     default: "",
 })

Edit system/core/rootdir/asan.options if needed. For instance, abort_on_error=0 will avoid abort() at the time asan detects something.

4. build with SANITIZE_TARGET=address

export SANITIZE_TARGET=address before running make. For other steps, here is example.

source build/envsetup.sh
lunch aosp_trout_x86_64-trung_staging-userdebug
export SANITIZE_TARGET=address
m

After build completed, make sure userdata.img is picked from build outcome. When ASAN option is enabled, some of library will be installed on /data so that userdata.img will contain ASAN enabled libraries. If userdata.img is wiped or separately created, these ASAN enabled libraries cannot be located by programs.

Reference