BoundsSanitizer (BoundSan) adds instrumentation to binaries to insert bounds checks around array accesses. These checks are added if the compiler cannot prove at compile time that the access will be safe and if the size of the array will be known at runtime, so that it can be checked against. Android 10 deploys BoundSan in Bluetooth and codecs. BoundSan is provided by the compiler and is enabled by default in various components throughout the platform.
Implementation
BoundSan uses UBSan's bounds sanitizer. This mitigation is enabled on a per-module level. It helps keep critical components of Android secure and shouldn't be disabled.
We strongly encourage you to enable BoundSan for additional components. Ideal candidates are privileged native code or complex native code that parses untrusted user input. The performance overhead associated with enabling BoundSan is dependent on the number of array accesses that can't be proven safe. Expect a small overhead percentage on average and test if performance is a concern.
Enabling BoundSan in blueprint files
BoundSan can be enabled in blueprint files by adding "bounds"
to the misc_undefined
sanitize property for binary and library
modules:
sanitize: { misc_undefined: ["bounds"], diag: { misc_undefined: ["bounds"], }, blacklist: "modulename_blacklist.txt",
diag
The diag
property enables diagnostics mode for the sanitizers.
Use diagnostics mode only during testing. Diagnostics mode doesn't abort on
overflows, which negates the security advantage of the mitigation and carries a
higher performance overhead, so it's not recommended for production builds.
blacklist
The blacklist
property allows the specification of a blacklist
file that developers can use to prevent functions and source files from being
sanitized. Use this property only if performance is a concern and the targeted
files/functions contribute substantially. Manually audit these files/functions
to ensure that array accesses are safe. See Troubleshooting for additional
details.
Enabling BoundSan in makefiles
BoundSan can be enabled in makefiles by adding "bounds"
to the LOCAL_SANITIZE
variable for binary and library modules:
LOCAL_SANITIZE := bounds # Optional features LOCAL_SANITIZE_DIAG := bounds LOCAL_SANITIZE_BLACKLIST := modulename_blacklist.txt
LOCAL_SANITIZE
accepts a list of sanitizers separated by a
comma.
LOCAL_SANITIZE_DIAG
turns on diagnostics mode. Use diagnostics
mode only during testing. Diagnostics mode doesn't abort on overflows, which
negates the security advantage of the mitigation and carries a higher
performance overhead, so it's not recommended for production builds.
LOCAL_SANITIZE_BLACKLIST
allows specification of a blacklist
file that allows developers to prevent functions and source files from being
sanitized. Use this property only if performance is a concern and the targeted
files/functions contribute substantially. Manually audit these files/functions
to ensure that array accesses are safe. See Troubleshooting for additional
details.
Disabling BoundSan
You can disable BoundSan in functions and source files with blacklists or function attributes. It's best to keep BoundSan enabled, so only disable it if the function or file is creating a large amount of performance overhead and the source has been manually reviewed.
For more Information on disabling BoundSan with function attributes and blacklist file formatting, refer to the Clang LLVM documentation. Scope the blacklisting to the particular sanitizer by using section names specifying the target sanitizer to avoid impacting other sanitizers.
Validation
There are no CTS test specifically for BoundSan. Instead, make sure that CTS tests pass with or without BoundSan enabled to verify that it isn't impacting the device.
Troubleshooting
Thoroughly test components after enabling BoundSan to ensure that any previously undetected out-of-bounds accesses are addressed.
BoundSan errors can be easily identified as they include the following tombstone abort message:
pid: ###, tid: ###, name: Binder:### >>> /system/bin/foobar <<< signal 6 (SIGABRT), code -6 (SI_TKILL), fault addr -------- Abort message: 'ubsan: out-of-bounds'
When running in diagnostics mode, the source file, line number, and index
value are printed to logcat
. By default, this mode doesn't
throw an abort message. Review logcat
to check for any
errors.
external/foo/bar.c:293:13: runtime error: index -1 out of bounds for type 'int [24]'