milan-avb: move teh descriptor FAM at the end of the structure to avoid overflow

This commit is contained in:
hackerman-kl 2026-04-26 13:03:10 +02:00 committed by Wim Taymans
parent 4d33f57325
commit 0bf4864d84
14 changed files with 126 additions and 204 deletions

View file

@ -53,7 +53,7 @@ int handle_cmd_get_dynamic_info_milan_v12(struct aecp *aecp, int64_t now,
if (entity_desc == NULL)
return reply_status(aecp, AVB_AECP_AEM_STATUS_NO_SUCH_DESCRIPTOR, m, len);
entity = (const struct avb_aem_desc_entity *)entity_desc->ptr;
entity = (const struct avb_aem_desc_entity *)descriptor_body(entity_desc);
if (config_idx >= ntohs(entity->configurations_count))
return reply_status(aecp, AVB_AECP_AEM_STATUS_NO_SUCH_DESCRIPTOR, m, len);
@ -76,7 +76,7 @@ int handle_cmd_get_dynamic_info_milan_v12(struct aecp *aecp, int64_t now,
switch (d->type) {
case AVB_AEM_DESC_ENTITY: {
const struct avb_aem_desc_entity *e =
(const struct avb_aem_desc_entity *)d->ptr;
(const struct avb_aem_desc_entity *)descriptor_body(d);
struct avb_aem_dynamic_info_entity rec;
if (size + sizeof(rec) > sizeof(buf)) {
@ -95,7 +95,7 @@ int handle_cmd_get_dynamic_info_milan_v12(struct aecp *aecp, int64_t now,
}
case AVB_AEM_DESC_AUDIO_UNIT: {
const struct avb_aem_desc_audio_unit *au =
(const struct avb_aem_desc_audio_unit *)d->ptr;
(const struct avb_aem_desc_audio_unit *)descriptor_body(d);
struct avb_aem_dynamic_info_audio_unit rec;
if (size + sizeof(rec) > sizeof(buf)) {
@ -112,8 +112,8 @@ int handle_cmd_get_dynamic_info_milan_v12(struct aecp *aecp, int64_t now,
break;
}
case AVB_AEM_DESC_STREAM_INPUT: {
const struct aecp_aem_stream_input_state *state =
(const struct aecp_aem_stream_input_state *)d->ptr;
const struct avb_aem_desc_stream *body =
(const struct avb_aem_desc_stream *)descriptor_body(d);
struct avb_aem_dynamic_info_stream rec;
if (size + sizeof(rec) > sizeof(buf)) {
@ -124,10 +124,11 @@ int handle_cmd_get_dynamic_info_milan_v12(struct aecp *aecp, int64_t now,
rec.hdr.descriptor_type = htons(d->type);
rec.hdr.descriptor_index = htons(d->index);
rec.stream_id = 0;
rec.stream_format = state->desc.current_format;
if (state->desc.current_format != 0)
rec.stream_format = body->current_format;
if (body->current_format != 0) {
rec.stream_info_flags =
htonl(AVB_AEM_STREAM_INFO_FLAG_STREAM_FORMAT_VALID);
}
memcpy(ptr, &rec, sizeof(rec));
ptr += sizeof(rec);
psize += sizeof(rec);
@ -135,8 +136,8 @@ int handle_cmd_get_dynamic_info_milan_v12(struct aecp *aecp, int64_t now,
break;
}
case AVB_AEM_DESC_STREAM_OUTPUT: {
const struct aecp_aem_stream_output_state *state =
(const struct aecp_aem_stream_output_state *)d->ptr;
const struct avb_aem_desc_stream *body =
(const struct avb_aem_desc_stream *)descriptor_body(d);
struct avb_aem_dynamic_info_stream rec;
if (size + sizeof(rec) > sizeof(buf)) {
@ -147,10 +148,11 @@ int handle_cmd_get_dynamic_info_milan_v12(struct aecp *aecp, int64_t now,
rec.hdr.descriptor_type = htons(d->type);
rec.hdr.descriptor_index = htons(d->index);
rec.stream_id = 0;
rec.stream_format = state->desc.current_format;
if (state->desc.current_format != 0)
rec.stream_format = body->current_format;
if (body->current_format != 0) {
rec.stream_info_flags =
htonl(AVB_AEM_STREAM_INFO_FLAG_STREAM_FORMAT_VALID);
}
memcpy(ptr, &rec, sizeof(rec));
ptr += sizeof(rec);
psize += sizeof(rec);
@ -159,7 +161,7 @@ int handle_cmd_get_dynamic_info_milan_v12(struct aecp *aecp, int64_t now,
}
case AVB_AEM_DESC_CLOCK_DOMAIN: {
const struct avb_aem_desc_clock_domain *cd =
(const struct avb_aem_desc_clock_domain *)d->ptr;
(const struct avb_aem_desc_clock_domain *)descriptor_body(d);
struct avb_aem_dynamic_info_clock_domain rec;
if (size + sizeof(rec) > sizeof(buf)) {

View file

@ -89,7 +89,7 @@ int handle_cmd_get_clock_source_milan_v12(struct aecp *aecp, int64_t now,
return reply_status(aecp,
AVB_AECP_AEM_STATUS_NO_SUCH_DESCRIPTOR, m, len);
dclk_domain = (struct avb_aem_desc_clock_domain*) desc->ptr;
dclk_domain = (struct avb_aem_desc_clock_domain*) descriptor_body(desc);
/** Descriptors always keep the network endianness */
sclk_source->clock_source_index = dclk_domain->clock_source_index;
@ -134,7 +134,7 @@ int handle_cmd_set_clock_source_milan_v12(struct aecp *aecp, int64_t now,
return reply_status(aecp,
AVB_AECP_AEM_STATUS_NO_SUCH_DESCRIPTOR, m, len);
dclk_domain = (struct avb_aem_desc_clock_domain *) desc->ptr;
dclk_domain = (struct avb_aem_desc_clock_domain *) descriptor_body(desc);
if (clock_src_index >= dclk_domain->clock_sources_count) {
return reply_invalid_clock_source(aecp, dclk_domain, m, len);
}

View file

@ -25,7 +25,7 @@ static int handle_unsol_set_configuration_milan_v12(struct aecp *aecp, struct de
int rc;
memset(buf, 0, sizeof(buf));
entity_desc = (struct avb_aem_desc_entity*) desc->ptr;
entity_desc = (struct avb_aem_desc_entity*) descriptor_body(desc);
cfg = (struct avb_packet_aecp_aem_setget_configuration *) p->payload;
cfg->configuration_index = htons(entity_desc->current_configuration);
p->aecp.target_guid = htobe64(aecp->server->entity_id);
@ -97,7 +97,7 @@ int handle_cmd_set_configuration_milan_v12(struct aecp *aecp, int64_t now,
p_reply = SPA_PTROFF(h_reply, sizeof(*h_reply), void);
cfg = (struct avb_packet_aecp_aem_setget_configuration*) p_reply->payload;
entity_desc = (struct avb_aem_desc_entity*) desc->ptr;
entity_desc = (struct avb_aem_desc_entity*) descriptor_body(desc);
cur_cfg_id = ntohs(entity_desc->current_configuration);
req_cfg_id = ntohs(cfg->configuration_index);
cfg_count = ntohs(entity_desc->configurations_count);
@ -182,7 +182,7 @@ int handle_cmd_get_configuration_common(struct aecp *aecp, int64_t now,
p_reply = SPA_PTROFF(h_reply, sizeof(*h_reply), void);
cfg = (struct avb_packet_aecp_aem_setget_configuration*) p_reply->payload;
entity_desc = (struct avb_aem_desc_entity*) desc->ptr;
entity_desc = (struct avb_aem_desc_entity*) descriptor_body(desc);
if (entity_desc->entity_id != p->aecp.target_guid) {
pw_log_error("Invalid entity id");

View file

@ -109,7 +109,7 @@ static int handle_cmd_get_control_identify(struct aecp *aecp, struct descriptor
struct avb_packet_aecp_aem_setget_control *ae_reply;
int pkt_size;
ctrl_desc = desc->ptr;
ctrl_desc = descriptor_body(desc);
desc_formats = ctrl_desc->value_format;
if (len < 0 || (size_t)len > sizeof(buf))
@ -145,7 +145,7 @@ static int handle_cmd_set_control_identify(struct aecp *aecp, struct descriptor
int rc;
control = (struct avb_packet_aecp_aem_setget_control*)p->payload;
ctrl_desc = desc->ptr;
ctrl_desc = descriptor_body(desc);
desc_formats = ctrl_desc->value_format;
old_value_format = desc_formats;
value_req = (uint8_t *)control->payload;
@ -265,7 +265,7 @@ int handle_cmd_set_control_milan_v12(struct aecp *aecp, int64_t now,
return reply_status(aecp,
AVB_AECP_AEM_STATUS_NO_SUCH_DESCRIPTOR, p, len);
ctrl_desc = desc->ptr;
ctrl_desc = descriptor_body(desc);
control_type = htobe64(ctrl_desc->control_type);
setter_cb = get_ctrl_setter_common(controls_handlers,
SPA_N_ELEMENTS(controls_handlers), control_type);
@ -307,7 +307,7 @@ int handle_cmd_get_control_milan_v12(struct aecp *aecp, int64_t now,
return reply_status(aecp,
AVB_AECP_AEM_STATUS_NO_SUCH_DESCRIPTOR, p, len);
ctrl_desc = desc->ptr;
ctrl_desc = descriptor_body(desc);
control_type = htobe64(ctrl_desc->control_type);
getter_cb = get_ctrl_getter_common(controls_handlers,
SPA_N_ELEMENTS(controls_handlers), control_type);

View file

@ -119,7 +119,7 @@ int handle_cmd_get_name_common(struct aecp *aecp, int64_t now,
return reply_status(aecp,
AVB_AECP_AEM_STATUS_NO_SUCH_DESCRIPTOR, m, len);
name_ptr = get_name_ptr(desc_type, desc->ptr, name_index);
name_ptr = get_name_ptr(desc_type, descriptor_body(desc), name_index);
if (name_ptr == NULL)
return reply_status(aecp,
AVB_AECP_AEM_STATUS_BAD_ARGUMENTS, m, len);
@ -169,7 +169,7 @@ int handle_cmd_set_name_common(struct aecp *aecp, int64_t now,
return reply_status(aecp,
AVB_AECP_AEM_STATUS_NO_SUCH_DESCRIPTOR, m, len);
name_ptr = get_name_ptr(desc_type, desc->ptr, name_index);
name_ptr = get_name_ptr(desc_type, descriptor_body(desc), name_index);
if (name_ptr == NULL)
return reply_status(aecp,
AVB_AECP_AEM_STATUS_BAD_ARGUMENTS, m, len);

View file

@ -155,7 +155,7 @@ int handle_cmd_set_sampling_rate_milan_v12(struct aecp *aecp, int64_t now,
AVB_AECP_AEM_STATUS_NO_SUCH_DESCRIPTOR, p, len);
if (desc_type == AVB_AEM_DESC_AUDIO_UNIT) {
struct avb_aem_desc_audio_unit *unit = desc->ptr;
struct avb_aem_desc_audio_unit *unit = descriptor_body(desc);
/* TODO check if the STREAM_PORT associated with it supportes
* the SSRC/ASRC bit.
*/
@ -218,7 +218,7 @@ int handle_cmd_get_sampling_rate_common(struct aecp *aecp, int64_t now,
AVB_AECP_AEM_STATUS_NO_SUCH_DESCRIPTOR, p, len);
if (desc_type == AVB_AEM_DESC_AUDIO_UNIT) {
struct avb_aem_desc_audio_unit *unit = desc->ptr;
struct avb_aem_desc_audio_unit *unit = descriptor_body(desc);
memcpy(&pullfreq, &unit->current_sampling_rate, sizeof(pullfreq));
} else {
return reply_status(aecp,

View file

@ -62,7 +62,7 @@ int handle_cmd_get_stream_format_milan_v12(struct aecp *aecp, int64_t now,
return reply_status(aecp,
AVB_AECP_AEM_STATUS_BAD_ARGUMENTS, m, len);
stream_desc = (struct avb_aem_desc_stream *)desc->ptr;
stream_desc = (struct avb_aem_desc_stream *)descriptor_body(desc);
if (len < 0 || (size_t)len > sizeof(buf))
return reply_status(aecp,
@ -120,7 +120,7 @@ int handle_cmd_set_stream_format_milan_v12(struct aecp *aecp, int64_t now,
AVB_AECP_AEM_STATUS_BAD_ARGUMENTS, m, len);
}
stream_desc = (struct avb_aem_desc_stream *)desc->ptr;
stream_desc = (struct avb_aem_desc_stream *)descriptor_body(desc);
for (i = 0; i < ntohs(stream_desc->number_of_formats); i++) {
if (stream_desc->stream_formats[i] == new_format) {
found = true;

View file

@ -92,9 +92,11 @@ static int build_stream_info_response(struct aecp *aecp, const void *m, int len,
}
static void populate_input_response(struct aecp *aecp,
struct aecp_aem_stream_input_state_milan_v12 *si,
struct descriptor *desc,
struct avb_packet_aecp_aem_setget_stream_info *reply)
{
struct aecp_aem_stream_input_state_milan_v12 *si = desc->ptr;
const struct avb_aem_desc_stream *stream_body = descriptor_body(desc);
struct stream_common *sc = &si->stream_in_sta.common;
struct avb_msrp_attribute *lattr = &sc->lstream_attr;
struct avb_msrp_attribute *taattr = &sc->tastream_attr;
@ -111,7 +113,7 @@ static void populate_input_response(struct aecp *aecp,
bool bound, settled, ta_observed, tf_observed, registering;
(void)aecp;
stream_format_be = si->stream_in_sta.desc.current_format;
stream_format_be = stream_body->current_format;
/* Milan Section 5.3.8.2: bound iff the listener has a saved talker stream id. */
bound = (lattr->attr.listener.stream_id != 0);
@ -194,7 +196,7 @@ static void populate_input_response(struct aecp *aecp,
}
static int handle_get_stream_input(struct aecp *aecp, const void *m, int len,
struct aecp_aem_stream_input_state_milan_v12 *si)
struct descriptor *desc)
{
uint8_t buf[2048];
struct avb_ethernet_header *h_reply;
@ -207,15 +209,17 @@ static int handle_get_stream_input(struct aecp *aecp, const void *m, int len,
p_reply = SPA_PTROFF(h_reply, sizeof(*h_reply), void);
reply = (struct avb_packet_aecp_aem_setget_stream_info *)p_reply->payload;
populate_input_response(aecp, si, reply);
populate_input_response(aecp, desc, reply);
return reply_success(aecp, buf, AVB_AECP_GET_STREAM_INFO_RESPONSE_LEN);
}
static void populate_output_response(struct aecp *aecp, uint16_t desc_index,
struct aecp_aem_stream_output_state *so,
struct descriptor *desc,
struct avb_packet_aecp_aem_setget_stream_info *reply)
{
struct aecp_aem_stream_output_state *so = desc->ptr;
const struct avb_aem_desc_stream *stream_body = descriptor_body(desc);
struct stream_common *sc = &so->common;
struct avb_msrp_attribute *taattr = &sc->tastream_attr;
const uint8_t zero_mac[6] = {0};
@ -275,21 +279,21 @@ static void populate_output_response(struct aecp *aecp, uint16_t desc_index,
build_stream_info_response(aecp, NULL, 0, reply,
flags_host, flags_ex_host,
0, 0,
so->desc.current_format, stream_id_be,
stream_body->current_format, stream_id_be,
so->presentation_time_offset_ns, dest_mac,
0, 0, vlan_id_host);
pw_log_debug("populate STREAM_OUTPUT stream_format=0x%016" PRIx64
" flags=0x%08x flags_ex=0x%08x pres_time_off=%u "
"stream_id=0x%016" PRIx64,
be64toh(so->desc.current_format),
be64toh(stream_body->current_format),
flags_host, flags_ex_host,
so->presentation_time_offset_ns,
be64toh(stream_id_be));
}
static int handle_get_stream_output(struct aecp *aecp, const void *m, int len,
uint16_t desc_index, struct aecp_aem_stream_output_state *so)
uint16_t desc_index, struct descriptor *desc)
{
uint8_t buf[2048];
struct avb_ethernet_header *h_reply;
@ -302,7 +306,7 @@ static int handle_get_stream_output(struct aecp *aecp, const void *m, int len,
p_reply = SPA_PTROFF(h_reply, sizeof(*h_reply), void);
reply = (struct avb_packet_aecp_aem_setget_stream_info *)p_reply->payload;
populate_output_response(aecp, desc_index, so, reply);
populate_output_response(aecp, desc_index, desc, reply);
return reply_success(aecp, buf, AVB_AECP_GET_STREAM_INFO_RESPONSE_LEN);
}
@ -324,12 +328,12 @@ int handle_cmd_get_stream_info_milan_v12(struct aecp *aecp, int64_t now,
if (desc == NULL)
return reply_status(aecp, AVB_AECP_AEM_STATUS_NO_SUCH_DESCRIPTOR, m, len);
if (desc_type == AVB_AEM_DESC_STREAM_INPUT)
return handle_get_stream_input(aecp, m, len,
(struct aecp_aem_stream_input_state_milan_v12 *)desc->ptr);
if (desc_type == AVB_AEM_DESC_STREAM_OUTPUT)
return handle_get_stream_output(aecp, m, len, desc_index,
(struct aecp_aem_stream_output_state *)desc->ptr);
if (desc_type == AVB_AEM_DESC_STREAM_INPUT) {
return handle_get_stream_input(aecp, m, len, desc);
}
if (desc_type == AVB_AEM_DESC_STREAM_OUTPUT) {
return handle_get_stream_output(aecp, m, len, desc_index, desc);
}
return reply_status(aecp, AVB_AECP_AEM_STATUS_BAD_ARGUMENTS, m, len);
}
@ -438,14 +442,11 @@ void cmd_get_stream_info_emit_unsol_milan_v12(struct server *server,
body->descriptor_type = htons(desc_type);
body->descriptor_index = htons(desc_index);
if (desc_type == AVB_AEM_DESC_STREAM_INPUT)
populate_input_response(aecp,
(struct aecp_aem_stream_input_state_milan_v12 *)desc->ptr,
body);
else
populate_output_response(aecp, desc_index,
(struct aecp_aem_stream_output_state *)desc->ptr,
body);
if (desc_type == AVB_AEM_DESC_STREAM_INPUT) {
populate_input_response(aecp, desc, body);
} else {
populate_output_response(aecp, desc_index, desc, body);
}
(void)reply_unsolicited_notifications(aecp, &b_state, buf,
AVB_AECP_GET_STREAM_INFO_RESPONSE_LEN, true);