{"id":"CVE-2026-16514","summary":"Out-of-bounds read in gPTP Announce path-trace validation via unvalidated stepsRemoved","details":"gptp_mi_qualify_announce() in subsys/net/l2/ethernet/gptp/gptp_mi.c walks the Path Trace TLV of a received IEEE 802.1AS Announce message, comparing each clock identity against the local one. The loop bound was taken solely from the attacker-controlled wire field announce-\u003esteps_removed (accepted up to 254), never from announce-\u003etlv.len, which is the field that states how many identities the TLV actually carries. Because path_sequence is the flexible member of the wire TLV (struct gptp_path_trace_tlv) and GPTP_ANNOUNCE() yields a raw pointer into the received packet buffer, the memcmp() inside the loop can address memory well past the end of the received frame.\n\nThe stack's only length validation, GPTP_ANNOUNCE_CHECK_LEN(), requires the received gPTP payload to be exactly 68 + tlv.len bytes — so it does not constrain the loop, it guarantees the data is absent. An unauthenticated attacker on the same Ethernet segment can send a single Announce frame declaring tlv.len = 0 with steps_removed = 254; the frame passes the length check and reception path (net_gptp_recv() → gptp_handle_msg() → gptp_mi_qualify_announce()), which performs no authentication, and the loop then reads 255 entries of 8 bytes each — about 2 KB — beyond the end of the network buffer.\n\nThe impact is an out-of-bounds read. The bytes read are only used as a memcmp() operand and are never returned to the attacker, so there is no meaningful information disclosure; the practical risk is that the overread crosses a network buffer pool boundary into unmapped or MPU-protected memory and faults the networking RX thread, causing a denial of service. Exposure is limited to builds that enable the opt-in, experimental CONFIG_NET_GPTP (TSN/AVB deployments) and to attackers with layer-2 adjacency, since gPTP frames are sent to a link-local multicast address and are not routed.\n\nThe fix computes the true entry count as tlv.len / GPTP_CLOCK_ID_LEN and rejects the announce when steps_removed + 1 exceeds it, so the loop can no longer run past the data the packet-length check proved present.","aliases":["GHSA-mgxg-89rr-6855"],"modified":"2026-09-20T14:24:40.758579Z","published":"2026-09-18T14:30:11.895Z","database_specific":{"cna_assigner":"zephyr","cwe_ids":["CWE-125"],"osv_generated_from":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/16xxx/CVE-2026-16514.json"},"references":[{"type":"ADVISORY","url":"https://github.com/CVEProject/cvelistV5/tree/main/cves/2026/16xxx/CVE-2026-16514.json"},{"type":"ADVISORY","url":"https://github.com/zephyrproject-rtos/zephyr/security/advisories/GHSA-mgxg-89rr-6855"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-16514"},{"type":"FIX","url":"https://github.com/zephyrproject-rtos/zephyr/commit/a2c882db7a57cf08a06b4d27bead22b07a9c3c61"},{"type":"PACKAGE","url":"https://github.com/zephyrproject-rtos/zephyr"}],"affected":[{"ranges":[{"type":"GIT","repo":"https://github.com/zephyrproject-rtos/zephyr","events":[{"introduced":"d62e861a01a2f4455ae89d105aa9dbc4bef501c5"},{"fixed":"a2c882db7a57cf08a06b4d27bead22b07a9c3c61"}],"database_specific":{"source":["AFFECTED_FIELD","REFERENCES"],"extracted_events":[{"introduced":"1.13.0"},{"fixed":"4.4.2"}]}}],"versions":["v4.4.0","v4.4.0-rc3","v4.4.0-rc2","v4.4.0-rc1","v4.3.0","v4.3.0-rc3","v4.3.0-rc2","v4.3.0-rc1","v4.2.0","v4.2.0-rc3","v4.2.0-rc2","v4.2.0-rc1","v4.1.0","v4.1.0-rc3","v4.1.0-rc2","v4.1.0-rc1","v4.0.0","v4.0.0-rc3","v4.0.0-rc2","v4.0.0-rc1","v3.7.0","v3.7.0-rc3","v3.7.0-rc2","v3.7.0-rc1","v3.6.0","v3.6.0-rc3","v3.6.0-rc2","v3.6.0-rc1","zephyr-v3.5.0","v3.5.0","v3.5.0-rc3","v3.5.0-rc2","v3.5.0-rc1","zephyr-v3.4.0","v3.4.0","v3.4.0-rc3","v3.4.0-rc2","v3.4.0-rc1","zephyr-v3.3.0","v3.3.0","v3.3.0-rc3","v3.3.0-rc2","v3.3.0-rc1","zephyr-v3.2.0","v3.2.0","v3.2.0-rc3","v3.2.0-rc2","v3.2.0-rc1","zephyr-v3.1.0","v3.1.0","v3.1.0-rc3","v3.1.0-rc2","v3.1.0-rc1","zephyr-v3.0.0","v3.0.0","v3.0.0-rc3","v3.0.0-rc2","v3.0.0-rc1","v2.7.99","v2.7.0-rc3","v2.7.0-rc2","v2.7.0-rc1","zephyr-v2.6.0","v2.6.0","v2.6.0-rc3","v2.6.0-rc2","v2.6.0-rc1","zephyr-v2.5.0","v2.5.0","v2.5.0-rc4","v2.5.0-rc3","v2.5.0-rc2","v2.5.0-rc1","zephyr-v2.4.0","v2.4.0","v2.4.0-rc3","v2.4.0-rc2","v2.4.0-rc1","zephyr-v2.3.0","v2.3.0","v2.3.0-rc2","v2.3.0-rc1","zephyr-v2.1.0","v2.1.0","zephyr-v2.2.0","v2.2.0","v2.2.0-rc3","v2.2.0-rc2","v2.2.0-rc1","v2.1.0-rc3","v2.1.0-rc2","v2.1.0-rc1","zephyr-v2.0.0","v2.0.0","v2.0.0-rc3","v2.0.0-rc2","v2.0.0-rc1","zephyr-v1.14.0","v1.14.0","v1.14.0-rc3","v1.14.0-rc2","v1.14.0-rc1","zephyr-v1.13.0","v1.13.0"],"database_specific":{"vanir_signatures":[{"deprecated":false,"digest":{"function_hash":"171699812988887101258092833673346155433","length":628},"id":"CVE-2026-16514-01cd4567","signature_type":"Function","signature_version":"v1","source":"https://github.com/zephyrproject-rtos/zephyr/commit/a2c882db7a57cf08a06b4d27bead22b07a9c3c61","target":{"file":"subsys/net/l2/ethernet/gptp/gptp_mi.c","function":"gptp_mi_qualify_announce"}},{"deprecated":false,"digest":{"line_hashes":["156601889340813881162965876054471340259","227664613353912941693109819003951891156","113695076734863102507485835412543550387","158827219936494986288748932044039104933","336328040193835341808062767201011694452","28356323322783938766560060937823037717","69374054473230219883793376464938434513","57290263450521420308132385440301653333","26556363630233892545299397492252584007"],"threshold":0.9},"id":"CVE-2026-16514-dac10603","signature_type":"Line","signature_version":"v1","source":"https://github.com/zephyrproject-rtos/zephyr/commit/a2c882db7a57cf08a06b4d27bead22b07a9c3c61","target":{"file":"subsys/net/l2/ethernet/gptp/gptp_mi.c"}}],"source":"https://storage.googleapis.com/cve-osv-conversion/osv-output/CVE-2026-16514.json","vanir_signatures_modified":"2026-09-20T14:24:40Z"}}],"schema_version":"1.9.0","severity":[{"type":"CVSS_V3","score":"CVSS:3.1/AV:A/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:L"}]}