Skip to content

core: spmc: fix tx buffer overrun in the retrieve response - #7960

Merged
jenswikl merged 1 commit into
OP-TEE:masterfrom
anarchyj:anarchyj-patch-3
Aug 31, 2026
Merged

core: spmc: fix tx buffer overrun in the retrieve response#7960
jenswikl merged 1 commit into
OP-TEE:masterfrom
anarchyj:anarchyj-patch-3

Conversation

@anarchyj

Copy link
Copy Markdown
Contributor

check_retrieve_request() decides whether the FFA_MEM_RETRIEVE_RESP fits in the endpoint's tx buffer by subtracting the requester-supplied mem_access_size from the buffer length. create_retrieve_response() instead writes the response using the SPMC's own access descriptor size (struct ffa_mem_access_1_0 for FF-A <= 1.1, struct ffa_mem_access_1_2 for 1.2), and its address range loop writes one struct ffa_address_range per shared region without checking the space left.

An endpoint that retrieves with a mem_access_size smaller than the size the SPMC writes makes the estimate over-count the free space, so the check passes while the response is written past the end of the tx buffer. A malicious S-EL0 SP can drive this by negotiating FF-A 1.2, using a mem_access_size of sizeof(struct ffa_mem_access_common) and controlling how many regions the memory was shared with, causing the S-EL1 SPMC to write out of bounds into the SP's tx buffer.

Reserve the space using the same access descriptor size create_retrieve_response() writes, so the estimate matches the write.

Fixes: d45fc14 ("core: ffa: add missing field in memory access descriptor")

Comment thread core/arch/arm/kernel/spmc_sp_handler.c Outdated
@jenswikl

Copy link
Copy Markdown
Contributor

Reviewed-by: Jens Wiklander <jens.wiklander@oss.qualcomm.com>

check_retrieve_request() decides whether the FFA_MEM_RETRIEVE_RESP fits
in the endpoint's tx buffer by subtracting the requester-supplied
mem_access_size from the buffer length. create_retrieve_response()
instead writes the response using the SPMC's own access descriptor size
(struct ffa_mem_access_1_0 for FF-A <= 1.1, struct ffa_mem_access_1_2
for 1.2), and its address range loop writes one struct ffa_address_range
per shared region without checking the space left.

An endpoint that retrieves with a mem_access_size smaller than the size
the SPMC writes makes the estimate over-count the free space, so the
check passes while the response is written past the end of the tx
buffer. A malicious S-EL0 SP can drive this by negotiating FF-A 1.2,
using a mem_access_size of sizeof(struct ffa_mem_access_common) and
controlling how many regions the memory was shared with, causing the
S-EL1 SPMC to write out of bounds into the SP's tx buffer.

Reserve the space using the same access descriptor size
create_retrieve_response() writes, so the estimate matches the write.

Fixes: d45fc14 ("core: ffa: add missing field in memory access descriptor")
Signed-off-by: Guled Hasan <Law.Zoldyck@proton.me>
Reviewed-by: Jens Wiklander <jens.wiklander@oss.qualcomm.com>
@anarchyj

Copy link
Copy Markdown
Contributor Author

Applied.

@jenswikl
jenswikl merged commit d68a08b into OP-TEE:master Aug 31, 2026
58 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants