-
Notifications
You must be signed in to change notification settings - Fork 339
Description
Checklist (Please check before submitting)
- I reviewed the Contributing Guide.
- I performed a cursory search to see if the bug report is relevant, not redundant, nor in conflict with other tickets.
Describe the bug
TO_LAB's TO_LAB_EncodeOutputMessage() reads the message size from the CCSDS packet header via CFE_MSG_GetSize() and passes it directly as the send length to OS_SocketSendTo() without validating it against the actual Software Bus buffer allocation. A message with an inflated CCSDS Length field causes adjacent heap memory to be read and transmitted over UDP.
An attacker with the ability to inject a crafted message onto the Software Bus (for example, via CI_LAB UDP command ingress in a lab configuration) can set a small payload but an inflated CCSDS length, causing TO_LAB to transmit heap memory beyond the actual buffer boundary over the telemetry UDP stream.
To Reproduce
- Build cFS Draco with AddressSanitizer enabled
- Start cFS with CI_LAB and TO_LAB
- Send a UDP packet to CI_LAB with a valid CCSDS header but the Length field claiming 512 bytes for a 16-byte actual payload
- TO_LAB reads 512 bytes from the 16-byte buffer and transmits the adjacent 496 bytes of heap memory over UDP
- ASan confirms
heap-buffer-overflow READat the exact point wheresendto()reads past the buffer
Proof-of-concept source and ASan output are available upon request.
Expected behavior
The encode function should validate that the CCSDS-derived message size does not exceed the actual buffer allocation before passing it to sendto(). At minimum, the size should be clamped to CFE_MISSION_SB_MAX_SB_MSG_SIZE.
Code snips
apps/to_lab/fsw/src/to_lab_passthru_encode.c (lines 46-49):
CFE_MSG_Size_t SourceBufferSize;
ResultStatus = CFE_MSG_GetSize(&SourceBuffer->Msg, &SourceBufferSize);
*DestBufferOut = SourceBuffer;
*DestSizeOut = SourceBufferSize; // TRUSTS CCSDS HEADER, NO BOUNDS CHECKCFE_MSG_GetSize() computes size purely from CCSDS header:
*Size = (MsgPtr->CCSDS.Pri.Length[0] << 8) + MsgPtr->CCSDS.Pri.Length[1] + 7;Caller in apps/to_lab/fsw/src/to_lab_app.c (lines 313-322):
OsStatus = OS_SocketSendTo(TO_LAB_Global.TLMsockid, NetBufPtr, NetBufSize, &d_addr);Note: This is a downstream symptom of a systemic root cause where CFE_SB_TransmitMsg itself trusts the CCSDS header size for its memcpy. Fixing the root cause at the SB API level would remediate this and similar findings across the framework.
System observed on:
- Hardware: x86_64
- OS: Linux (Ubuntu 22.04, with ASan)
- Versions: cFS Draco release, commit
83c735e; TO_LAB passthru encode path