security: validate packet length in AVB IEC 61883 stream handler

Input Validation: High

The on_socket_data() handler only checked that the received packet was
at least avb_packet_header size before casting to avb_packet_iec61883,
which is larger. A packet between these two sizes would cause
out-of-bounds reads when accessing iec61883 fields like data_len.

Additionally, handle_iec61883_packet() used the data_len field from the
packet to determine how many bytes to copy into the ring buffer without
checking that the claimed data_len didn't exceed the actual received
data. A crafted packet with an inflated data_len could cause an
out-of-bounds read from the receive buffer.

Fix by requiring the minimum packet size to cover both the ethernet
header and the iec61883 header, and by validating that the claimed
payload size doesn't exceed the received data length.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Wim Taymans 2026-04-27 12:24:04 +02:00
parent 918d0f2f8a
commit 931505a0e4

View file

@ -366,6 +366,8 @@ static void handle_iec61883_packet(struct stream *stream,
if (data_len < 8)
return;
n_bytes = data_len - 8;
if (n_bytes > (uint32_t)(len - (int)sizeof(*p)))
return;
if (filled + n_bytes > stream->buffer_size) {
pw_log_debug("capture overrun");
@ -393,9 +395,11 @@ static void on_socket_data(void *data, int fd, uint32_t mask)
if (len < 0) {
pw_log_warn("got recv error: %m");
}
else if (len < (int)sizeof(struct avb_packet_header)) {
else if (len < (int)(sizeof(struct avb_ethernet_header) +
sizeof(struct avb_packet_iec61883))) {
pw_log_warn("short packet received (%d < %d)", len,
(int)sizeof(struct avb_packet_header));
(int)(sizeof(struct avb_ethernet_header) +
sizeof(struct avb_packet_iec61883)));
} else {
struct avb_ethernet_header *h = (void*)buffer;
struct avb_packet_iec61883 *p = SPA_PTROFF(h, sizeof(*h), void);