| Title | NASA cFS 7.0.0 CFE_SB_TransmitMsg memcpy trusts CCSDS header size without sourc |
|---|
| Description | CFE_SB_TransmitMsg() reads the message size from the CCSDS header and uses it as the memcpy length when copying from the caller's buffer to a new Software Bus buffer. The API has no SourceBufferSize parameter, so there is no way to validate that the caller's buffer actually contains the claimed number of bytes. If the CCSDS Length field exceeds the source buffer allocation, memcpy reads past the buffer into adjacent memory, and the over-read data is delivered to all subscribers of that message ID.
This is the systemic root cause behind multiple downstream findings: the TO_LAB UDP over-read (Heartbleed-pattern), the sch_lab table over-read, and the zero-copy size mismatch. Addressing this at the SB API level remediates all of them simultaneously.
On flat-memory RTOS deployments (VxWorks, RTEMS) without MMU isolation, this enables cross-application information disclosure. The maximum over-read is bounded by CFE_MISSION_SB_MAX_SB_MSG_SIZE (default 32,768 bytes).
To Reproduce
Allocate a small message buffer (e.g. 32 bytes) on the heap
Set the CCSDS Length field to claim a much larger size (e.g. 1024 bytes)
Call CFE_SB_TransmitMsg() with this buffer
The internal memcpy reads 1024 bytes from the 32-byte buffer - 992 bytes of adjacent memory are copied into the SB buffer and delivered to all subscribers
Confirmed with ASan: heap-buffer-overflow READ of size 1024 from a 32-byte region
Proof-of-concept source and ASan output are available upon request.
Expected behavior
CFE_SB_TransmitMsg() should validate that the CCSDS-derived message size does not exceed the actual source buffer size before performing the memcpy.
Code snips
API signature — no source buffer size parameter:
CFE_Status_t CFE_SB_TransmitMsg(const CFE_MSG_Message_t *MsgPtr, bool IsOrigination);
Step 1 — Read size from CCSDS header (cfe_sb_priv.c:861-893):
CFE_MSG_GetSize(MsgPtr, &MsgSize);
CFE_SB_MessageTxn_SetContentSize(TxnPtr, MsgSize);
Step 2 — Allocate destination buffer using CCSDS-derived size (cfe_sb_api.c:1491):
BufPtr = CFE_SB_AllocateMessageBuffer(CFE_SB_MessageTxn_GetContentSize(Txn));
Step 3 — memcpy using CCSDS size with no source bounds validation (cfe_sb_api.c:1513):
memcpy(&BufPtr->Msg, MsgPtr, CFE_SB_MessageTxn_GetContentSize(Txn));
System observed on:
Hardware: x86_64
OS: Linux (Ubuntu 22.04, with ASan)
Versions: cFS Draco release, commit 83c735e
Additional context
This is the most architecturally significant finding in the assessment. The Software Bus is the central message-passing mechanism in cFS — every application uses CFE_SB_TransmitMsg(). The CCSDS Length field is trusted as the sole source of truth for buffer sizing throughout the entire framework. Fixing this at the API level hardens the entire message path. |
|---|
| Source | ⚠️ https://github.com/nasa/cFS/issues/953 |
|---|
| User | 0rbitingZer0 (UID 96146) |
|---|
| Submission | 03/18/2026 01:32 (20 days ago) |
|---|
| Moderation | 04/03/2026 09:51 (16 days later) |
|---|
| Status | Accepted |
|---|
| VulDB entry | 355079 [NASA cFS up to 7.0.0 CCSDS Header Size cfe_sb_priv.c CFE_SB_TransmitMsg memory corruption] |
|---|
| Points | 20 |
|---|