Spec mismatch in NovAtel parser
Bug Report
Issue details
The NovAtel binary GPS parser applies its payload-buffer limit to the total number of bytes read, including the message header, even though the destination buffer contains only payload data.
The payload buffer has a capacity of 256 bytes:
union PACKED msgbuffer {
bestvel bestvelu;
bestpos bestposu;
psrdop psrdopu;
uint8_t bytes[256];
};During the DATA state, the parser performs the following check:
if (nova_msg.read >= sizeof(nova_msg.data)) {
Debug("parse data overflow length=%u msglength=%u\n",
(unsigned)nova_msg.read,
nova_msg.header.nova_headeru.messagelength);
nova_msg.nova_state = nova_msg_parser::PREAMBLE1;
break;
}
nova_msg.data.bytes[
nova_msg.read -
nova_msg.header.nova_headeru.headerlength] = temp;nova_msg.read counts both header and payload bytes. With the normal 28-byte NovAtel binary header, the check therefore limits the effective payload capacity to:
256 - 28 = 228 bytesA 228-byte payload is accepted. When the parser receives byte 229 of a longer payload, nova_msg.read is already 256, so it resets before copying the byte. The message never reaches CRC validation or process_message().
This does not appear likely to affect ArduPilot’s normal NovAtel configuration. The driver executes unlogall and requests only:
BESTPOSB
BESTVELB
PSRDOPBBESTPOSB has a 72-byte payload and BESTVELB has a 44-byte payload, so neither approaches the defective boundary.
PSRDOPB has a variable payload length:
28 + (4 × number of PRNs)It would exceed 228 bytes only when listing at least 51 PRNs. We have not demonstrated that a currently supported NovAtel, Tersus, or ComNav receiver emits such a PSRDOPB message during ordinary ArduPilot operation.
Nevertheless, this is a specification and implementation mismatch. The NovAtel protocol supports valid messages larger than 228 bytes. For example, a binary RANGE payload contains four initial bytes followed by 44 bytes per observation, so a valid message with six observations already has a 268-byte payload. ArduPilot does not normally request or process RANGE, but it demonstrates that 228 bytes is not a protocol-wide payload limit.
Accordingly, this report is not claiming a currently observed operational failure or security vulnerability. It identifies a defensive parser bug that unnecessarily reduces the declared payload-buffer capacity from 256 bytes to 228 bytes. It could become visible if a future supported message is larger, if PSRDOPB contains enough PRNs, or if the receiver is configured independently to emit additional binary logs.
The boundary check should use the payload offset:
const uint16_t payload_offset =
nova_msg.read -
nova_msg.header.nova_headeru.headerlength;
if (payload_offset >= sizeof(nova_msg.data.bytes)) {
Debug("parse data overflow offset=%u msglength=%u\n",
(unsigned)payload_offset,
nova_msg.header.nova_headeru.messagelength);
nova_msg.nova_state = nova_msg_parser::PREAMBLE1;
break;
}
nova_msg.data.bytes[payload_offset] = temp;The parser could also reject messagelength > sizeof(nova_msg.data.bytes) immediately after reading the header.
Version
ArduPilot revision 4fe7ad4fab8c1bf4ade7cbc7ae85a73c81d73e05.
The same comparison is also present on the current master branch as of August 22, 2026.
Platform
- All
- AntennaTracker
- Copter
- Plane
- Rover
- Submarine
The code is part of the shared GPS backend and is not specific to a vehicle type.
Airframe type
Not airframe-specific.
Hardware type
Any autopilot using the AP_GPS_NOVA backend with a NovAtel-compatible GPS receiver. No currently affected hardware configuration has been demonstrated.
Logs
No flight logs are available. This report concerns a code-level parser/specification mismatch and is not based on an observed flight failure.
Source: ArduPilot/ardupilot