BoundsSanitizer

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]'