nasa / nasa/cFS

[SECURITY] Heap over-read via untrusted CCSDS length in TO_LAB sendto

Open
#952 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
C
Stars
1.5k
Forks
391
Avg merge
1d 11h
Merged PRs (30d)
19

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

  1. Build cFS Draco with AddressSanitizer enabled
  2. Start cFS with CI_LAB and TO_LAB
  3. 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
  4. TO_LAB reads 512 bytes from the 16-byte buffer and transmits the adjacent 496 bytes of heap memory over UDP
  5. ASan confirms heap-buffer-overflow READ at the exact point where sendto() 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 CHECK

CFE_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

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with apps/to_lab/fsw/src/to_lab_passthru_encode.c and apps/to_lab/fsw/src/to_lab_app.c, then inspect CFE_MSG_GetSize and the Software Bus path noted in the issue. Reproduce the crafted-length case with the ASan-enabled cFS Draco build. Done means the send path cannot read or transmit beyond the allocated message buffer, with the reported heap-buffer-overflow no longer occurring.

Written by the indexing model from the issue text.

Assessment

Tech stack
c
Domain
networking, security
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.