mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2026-04-29 06:46:38 -04:00
security: validate packet length in AVB AECP AEM command handlers
Memory Safety: High Multiple AVB AECP AEM command handler functions copied network packet data into stack buffers via memcpy(buf, m, len) without validating that len fits within the destination buffer. A crafted AVB packet with an oversized length could overflow the stack buffer. Added bounds validation before each memcpy in: - cmd-available.c: handle_cmd_entity_available_milan_v12 - cmd-get-set-configuration.c: set and get configuration handlers - cmd-get-set-sampling-rate.c: unsolicited, invalid response, and get handlers - cmd-get-set-stream-format.c: get and set stream format handlers - cmd-lock-entity.c: handle_cmd_lock_entity_milan_v12 This matches the bounds checking pattern already used in cmd-get-set-control.c, cmd-get-set-clock-source.c, and cmd-get-set-name.c. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
0bd9a4d033
commit
710414730d
5 changed files with 34 additions and 0 deletions
|
|
@ -49,6 +49,10 @@ int handle_cmd_entity_available_milan_v12(struct aecp *aecp, int64_t now, const
|
|||
entity_state = desc->ptr;
|
||||
lock = &entity_state->state.lock_state;
|
||||
|
||||
if (len < 0 || (size_t)len > sizeof(buf))
|
||||
return reply_status(aecp,
|
||||
AVB_AECP_AEM_STATUS_BAD_ARGUMENTS, p, len);
|
||||
|
||||
/* Forge the response for the entity that is locking the device */
|
||||
memcpy(buf, m, len);
|
||||
h_reply = (struct avb_ethernet_header *) buf;
|
||||
|
|
|
|||
|
|
@ -87,6 +87,10 @@ int handle_cmd_set_configuration_milan_v12(struct aecp *aecp, int64_t now,
|
|||
return reply_status(aecp,
|
||||
AVB_AECP_AEM_STATUS_NO_SUCH_DESCRIPTOR, p, len);
|
||||
|
||||
if (len < 0 || (size_t)len > sizeof(buf))
|
||||
return reply_status(aecp,
|
||||
AVB_AECP_AEM_STATUS_BAD_ARGUMENTS, p, len);
|
||||
|
||||
// TODO maybe avoid copy here
|
||||
memcpy(buf, m, len);
|
||||
h_reply = (struct avb_ethernet_header *)buf;
|
||||
|
|
@ -169,6 +173,10 @@ int handle_cmd_get_configuration_common(struct aecp *aecp, int64_t now,
|
|||
return reply_status(aecp,
|
||||
AVB_AECP_AEM_STATUS_NO_SUCH_DESCRIPTOR, p, len);
|
||||
|
||||
if (len < 0 || (size_t)len > sizeof(buf))
|
||||
return reply_status(aecp,
|
||||
AVB_AECP_AEM_STATUS_BAD_ARGUMENTS, p, len);
|
||||
|
||||
memcpy(buf, m, len);
|
||||
h_reply = (struct avb_ethernet_header *)buf;
|
||||
p_reply = SPA_PTROFF(h_reply, sizeof(*h_reply), void);
|
||||
|
|
|
|||
|
|
@ -84,6 +84,9 @@ static int send_unsol_get_sampling_rate_milan_v12(struct aecp *aecp,
|
|||
struct aecp_aem_base_info info = { 0 };
|
||||
int rc = 0;
|
||||
|
||||
if (len > sizeof(unsol_buf))
|
||||
return -EINVAL;
|
||||
|
||||
memcpy(unsol_buf, m, len);
|
||||
/* Prepare a template packet */
|
||||
info.controller_entity_id = htobe64(ctrler_id);
|
||||
|
|
@ -106,6 +109,9 @@ static int sample_rate_invalid_response(struct aecp *aecp,
|
|||
struct avb_packet_aecp_aem *p = SPA_PTROFF(h, sizeof(*h), void);
|
||||
struct avb_packet_aecp_aem_setget_sampling_rate *cmd;
|
||||
|
||||
if (len > sizeof(buf))
|
||||
return -EINVAL;
|
||||
|
||||
memcpy(buf, m, len);
|
||||
cmd = (struct avb_packet_aecp_aem_setget_sampling_rate *)p->payload;
|
||||
|
||||
|
|
@ -219,6 +225,10 @@ int handle_cmd_get_sampling_rate_common(struct aecp *aecp, int64_t now,
|
|||
AVB_AECP_AEM_STATUS_NOT_IMPLEMENTED, p, len);
|
||||
}
|
||||
|
||||
if (len < 0 || (size_t)len > sizeof(buf))
|
||||
return reply_status(aecp,
|
||||
AVB_AECP_AEM_STATUS_BAD_ARGUMENTS, p, len);
|
||||
|
||||
memcpy(buf, m, len);
|
||||
h_reply = (struct avb_ethernet_header *)buf;
|
||||
reply_p = SPA_PTROFF(h_reply, sizeof(*h_reply), void);
|
||||
|
|
|
|||
|
|
@ -64,6 +64,10 @@ int handle_cmd_get_stream_format_milan_v12(struct aecp *aecp, int64_t now,
|
|||
|
||||
stream_desc = (struct avb_aem_desc_stream *)desc->ptr;
|
||||
|
||||
if (len < 0 || (size_t)len > sizeof(buf))
|
||||
return reply_status(aecp,
|
||||
AVB_AECP_AEM_STATUS_BAD_ARGUMENTS, m, len);
|
||||
|
||||
memcpy(buf, m, len);
|
||||
h_reply = (struct avb_ethernet_header *)buf;
|
||||
p_reply = SPA_PTROFF(h_reply, sizeof(*h_reply), void);
|
||||
|
|
@ -133,6 +137,10 @@ int handle_cmd_set_stream_format_milan_v12(struct aecp *aecp, int64_t now,
|
|||
}
|
||||
|
||||
|
||||
if (len < 0 || (size_t)len > sizeof(buf))
|
||||
return reply_status(aecp,
|
||||
AVB_AECP_AEM_STATUS_BAD_ARGUMENTS, m, len);
|
||||
|
||||
memcpy(buf, m, len);
|
||||
h_reply = (struct avb_ethernet_header *)buf;
|
||||
p_reply = SPA_PTROFF(h_reply, sizeof(*h_reply), void);
|
||||
|
|
|
|||
|
|
@ -194,6 +194,10 @@ int handle_cmd_lock_entity_milan_v12(struct aecp *aecp, int64_t now, const void
|
|||
}
|
||||
}
|
||||
|
||||
if (len < 0 || (size_t)len > sizeof(buf))
|
||||
return reply_status(aecp,
|
||||
AVB_AECP_AEM_STATUS_BAD_ARGUMENTS, p, len);
|
||||
|
||||
/* Forge the response for the entity that is locking the device */
|
||||
memcpy(buf, m, len);
|
||||
h_reply = (struct avb_ethernet_header *) buf;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue