CVE-2026-0039 AI-generated analysis
platform/external/dng_sdk, libdng_sdk (DNG image parsing, exercised by ImageDecoder per the commit's Test line)
Rebuilds libdng_sdk so that UBSan signed/unsigned integer-overflow checks call a library-private runtime that throws std::runtime_error, replacing the ubsan-minimal runtime that hard-aborts the process when an overflow is detected.
Root cause
libdng_sdk inherits sanitize.misc_undefined: ["unsigned-integer-overflow", "signed-integer-overflow"] from libdng_sdk-defaults in Android.bp. With that configuration the ubsan-minimal runtime is linked, and its handlers abort the process on a detected overflow (the commit message calls this a 'hard abort'). Integer-overflow sites in the DNG code, referenced by the seven bug ids listed in the commit, therefore terminate the decoding process when a malformed DNG triggers them instead of failing the decode. The library already builds with rtti: true and cppflags: ["-fexceptions"], so an exception-based error path was available but the sanitizer did not use it.
How the fix works
- Android.bp :: cc_library libdng_sdk: adds sanitize: { never: true } to turn off Soong-managed sanitizers for this module, which per the inline comment disables the ubsan_minimal runtime and overrides the misc_undefined list inherited from libdng_sdk-defaults.
- Android.bp :: cc_library libdng_sdk: re-enables the same instrumentation manually with the cflags "-fsanitize=signed-integer-overflow,unsigned-integer-overflow" and adds "-fno-sanitize-link-runtime", so the compiler still emits __ubsan_handle_* calls but no sanitizer runtime is linked. "-DqDNGValidate=0" is kept.
- Android.bp :: cc_library libdng_sdk: adds srcs ubsan-replacement/ubsan_throwing_runtime.cpp to the library.
- ubsan-replacement/ubsan_throwing_runtime.cpp: defines extern "C" hidden-visibility __ubsan_handle_add_overflow, __ubsan_handle_sub_overflow, __ubsan_handle_mul_overflow, __ubsan_handle_negate_overflow and __ubsan_handle_divrem_overflow. Each throws std::runtime_error("ubsan: <kind>"), so a detected overflow now unwinds as a C++ exception (the library builds with -fexceptions) instead of aborting.
- OWNERS: metadata-only change (bug component and owner list), no functional effect.
Completeness
- The fix does not correct any of the individual overflowing arithmetic sites. It changes how every detected signed or unsigned overflow in libdng_sdk is reported, so all referenced bugs and any other such overflow in the library take the same exception path.
- Only five handler symbols are provided (add, sub, mul, negate, divrem). There are no _abort variants and no handlers for other UBSan checks, so enabling further -fsanitize checks or -fno-sanitize-recover on this module would need additional handlers.
- The change is scoped to the libdng_sdk module. libdng_sdk-defaults still carries misc_undefined, so any other module that uses those defaults (none shown in the material) would still get the default sanitizer runtime.
- The material does not show whether every call path into libdng_sdk catches std::runtime_error. An uncaught exception would still terminate the process via std::terminate.
Behavior changes
- Integer overflow detected during DNG processing now raises std::runtime_error("ubsan: add-overflow" / "sub-overflow" / "mul-overflow" / "negate-overflow" / "divrem-overflow") instead of aborting the process.
- libdng_sdk no longer links a sanitizer runtime (ubsan-minimal). The overflow instrumentation is still compiled in through cflags.
- The change applies to both device and host builds of libdng_sdk (host_supported: true).
Per major
- Android 14: same fix: commit 42e65547eb33 in android-security-14.0.0_r28. The Android.bp hunk and ubsan_throwing_runtime.cpp are identical to the other branches; only OWNERS differs. Code context at android-security-14.0.0_r29 shows the change in place (the per-major check reports 3/5 lines of the patched region present).
- Android 15: same fix: commit 1ec41401b3d4 in android-security-15.0.0_r16, with identical Android.bp (blob 1978b39..3d95a7b) and runtime file. OWNERS differs.
- Android 16: same fix: commit 74a5a91d169a in android-security-16.0.0_r7, with identical Android.bp and runtime file. OWNERS differs.
- Android 17: same fix: commit 7937f2f835ab (subject marked RESTRICT AUTOMERGE) is in the android-17.0.0_r1 base, with identical Android.bp and runtime file.
Unknowns
- The exact overflowing expressions behind the seven bug ids are not in the material.
- Which catch handlers (in dng_sdk or its callers such as the ImageDecoder native path) absorb std::runtime_error is not shown, so it is unverified whether every entry point turns the exception into a clean decode failure.
- The material does not explain why the bulletin rates this DoS as Critical.