FastRPC version
1bd8835 (vulnerable code is byte-identical on current development HEAD d247519)
DSP firmware version
ADSP.VT.5.4-00283-NICOBAR_1.0 (build 2019-09-04; strings dspso.bin, stock V12.0.26.0 vendor image)
SoC and device name
Qualcomm SM6125 (Snapdragon 665) — Xiaomi Mi A3 (laurel_sprout), running mainline Linux (NixOS)
Kernel version
7.3.0-rc1 (mainline)
What happened?
The ADSP default listener (adsprpcd audiopd) died with SIGSEGV in
__memcpy_generic called from listener() (libadsprpc.so+0x32c1c).
Forensics on the retained core: si_addr = input_buffer_base + 0xc8e8e6e7
against a 4 KiB input buffer; the last decoded length word on the stack was
0x6474735f (~1.57 GiB).
Root cause, reproduced on host and on the device itself with a minimal
gate that drives the real unpack_in_bufs():
unpack_in_bufs() (inc/listener_buf.h) advances the sbuf cursor by a
DSP-supplied 4-byte length without validating it. pra[].buf.pv is
only assigned when the original (int)len <= sbuf_left(buf) comparison
happens to hold; on mismatch pv is left stale/NULL while the cursor
still escapes the buffer.
sbuf_left() (inc/sbuf.h) subtracts two uintptr_t into an int.
With the escaped cursor the true remainder is -3370702567, which
overflows int32 and wraps to +924264729, so the caller's bounds check
passes and sbuf_read()'s memmove dereferences the wild cursor.
Gate results (lengths: 0x6474735f, remaining+1, 0x7fffffff, 0x80000000,
0xffffffff):
| headers |
result |
| original, host x86-64 |
SIGSEGV |
| original, device aarch64 (this phone) |
SIGSEGV |
AOSP android-17.0.0_r1, host |
SIGSEGV |
| patched (see linked PR), device aarch64 |
all contained, exit 0 |
This is the CVE-2020-11206 pattern ("buffer overflow in Fastrpc while
handling received parameters due to lack of validation on input
parameters"); SM6125 is in the affected list. The November 2020 fix shipped
only as a closed-source component, so this open-source tree never received
it — the identical unchecked pattern is still present on development HEAD
and in AOSP platform/external/fastrpc through android-17.0.0_r1.
Patch proposal linked: validates the length in unsigned arithmetic against
the true unsigned remainder before the cursor advances, and computes
sbuf_left unsigned with clamping. Patched fastrpc userspace has been
running on the device as the live audiopd listener since deployment:
Type=notify readiness reached, no SEGV, normal operation.
FastRPC version
1bd8835 (vulnerable code is byte-identical on current
developmentHEAD d247519)DSP firmware version
ADSP.VT.5.4-00283-NICOBAR_1.0 (build 2019-09-04; strings dspso.bin, stock V12.0.26.0 vendor image)
SoC and device name
Qualcomm SM6125 (Snapdragon 665) — Xiaomi Mi A3 (laurel_sprout), running mainline Linux (NixOS)
Kernel version
7.3.0-rc1 (mainline)
What happened?
The ADSP default listener (
adsprpcd audiopd) died with SIGSEGV in__memcpy_genericcalled fromlistener()(libadsprpc.so+0x32c1c).Forensics on the retained core:
si_addr = input_buffer_base + 0xc8e8e6e7against a 4 KiB input buffer; the last decoded length word on the stack was
0x6474735f(~1.57 GiB).Root cause, reproduced on host and on the device itself with a minimal
gate that drives the real
unpack_in_bufs():unpack_in_bufs()(inc/listener_buf.h) advances the sbuf cursor by aDSP-supplied 4-byte length without validating it.
pra[].buf.pvisonly assigned when the original
(int)len <= sbuf_left(buf)comparisonhappens to hold; on mismatch pv is left stale/NULL while the cursor
still escapes the buffer.
sbuf_left()(inc/sbuf.h) subtracts twouintptr_tinto anint.With the escaped cursor the true remainder is -3370702567, which
overflows int32 and wraps to +924264729, so the caller's bounds check
passes and
sbuf_read()'s memmove dereferences the wild cursor.Gate results (lengths: 0x6474735f, remaining+1, 0x7fffffff, 0x80000000,
0xffffffff):
android-17.0.0_r1, hostThis is the CVE-2020-11206 pattern ("buffer overflow in Fastrpc while
handling received parameters due to lack of validation on input
parameters"); SM6125 is in the affected list. The November 2020 fix shipped
only as a closed-source component, so this open-source tree never received
it — the identical unchecked pattern is still present on
developmentHEADand in AOSP
platform/external/fastrpcthrough android-17.0.0_r1.Patch proposal linked: validates the length in unsigned arithmetic against
the true unsigned remainder before the cursor advances, and computes
sbuf_leftunsigned with clamping. Patched fastrpc userspace has beenrunning on the device as the live audiopd listener since deployment:
Type=notify readiness reached, no SEGV, normal operation.