avb: bounds check the attribute encoding

Add a maxsize to the attribute encode functions and add checks that
they don't overwrite the provided buffer.
This commit is contained in:
Wim Taymans 2026-05-04 10:47:52 +02:00
parent cda2e2ee17
commit 7dacdc8cc8
2 changed files with 24 additions and 10 deletions

View file

@ -126,7 +126,7 @@ static int process_talker(struct msrp *msrp, uint64_t now, uint8_t attr_type,
return 0;
}
static int encode_talker(struct msrp *msrp, struct attr *a, void *m)
static int encode_talker(struct msrp *msrp, struct attr *a, void *m, size_t maxsize)
{
struct avb_packet_msrp_msg *msg = m;
struct avb_packet_mrp_vector *v;
@ -135,6 +135,9 @@ static int encode_talker(struct msrp *msrp, struct attr *a, void *m)
uint8_t *ev;
size_t attr_list_length = sizeof(*v) + sizeof(*t) + sizeof(*f) + 1;
if (attr_list_length + sizeof(*msg) > maxsize)
return -ENOSPC;
msg->attribute_type = AVB_MSRP_ATTRIBUTE_TYPE_TALKER_ADVERTISE;
msg->attribute_length = sizeof(*t);
msg->attribute_list_length = htons(attr_list_length);
@ -261,7 +264,7 @@ static int process_listener(struct msrp *msrp, uint64_t now, uint8_t attr_type,
}
return 0;
}
static int encode_listener(struct msrp *msrp, struct attr *a, void *m)
static int encode_listener(struct msrp *msrp, struct attr *a, void *m, size_t maxsize)
{
struct avb_packet_msrp_msg *msg = m;
struct avb_packet_mrp_vector *v;
@ -270,6 +273,9 @@ static int encode_listener(struct msrp *msrp, struct attr *a, void *m)
uint8_t *ev;
size_t attr_list_length = sizeof(*v) + sizeof(*l) + sizeof(*f) + 1 + 1;
if (attr_list_length + sizeof(*msg) > maxsize)
return -ENOSPC;
msg->attribute_type = AVB_MSRP_ATTRIBUTE_TYPE_LISTENER;
msg->attribute_length = sizeof(*l);
msg->attribute_list_length = htons(attr_list_length);
@ -342,7 +348,7 @@ static int process_domain(struct msrp *msrp, uint64_t now, uint8_t attr_type,
return 0;
}
static int encode_domain(struct msrp *msrp, struct attr *a, void *m)
static int encode_domain(struct msrp *msrp, struct attr *a, void *m, size_t maxsize)
{
struct avb_packet_msrp_msg *msg = m;
struct avb_packet_mrp_vector *v;
@ -351,6 +357,9 @@ static int encode_domain(struct msrp *msrp, struct attr *a, void *m)
uint8_t *ev;
size_t attr_list_length = sizeof(*v) + sizeof(*d) + sizeof(*f) + 1;
if (attr_list_length + sizeof(*msg) > maxsize)
return -ENOSPC;
msg->attribute_type = AVB_MSRP_ATTRIBUTE_TYPE_DOMAIN;
msg->attribute_length = sizeof(*d);
msg->attribute_list_length = htons(attr_list_length);
@ -375,7 +384,7 @@ static const struct {
const char *name;
int (*process) (struct msrp *msrp, uint64_t now, uint8_t attr_type,
const void *m, uint8_t event, uint8_t param, int num);
int (*encode) (struct msrp *msrp, struct attr *attr, void *m);
int (*encode) (struct msrp *msrp, struct attr *attr, void *m, size_t maxsize);
void (*notify) (struct msrp *msrp, uint64_t now, struct attr *attr, uint8_t notify);
} dispatch[] = {
[AVB_MSRP_ATTRIBUTE_TYPE_TALKER_ADVERTISE] = { "talker", process_talker, encode_talker, notify_talker, },
@ -514,7 +523,7 @@ static void msrp_event(void *data, uint64_t now, uint8_t event)
void *msg = SPA_PTROFF(buffer, sizeof(*p), void);
struct attr *a;
int len, count = 0;
size_t total = sizeof(*p) + 2;
size_t total = sizeof(*p) + sizeof(*f);
p->version = AVB_MRP_PROTOCOL_VERSION;
@ -528,7 +537,8 @@ static void msrp_event(void *data, uint64_t now, uint8_t event)
dispatch[a->attr->type].name,
avb_mrp_send_name(a->attr->mrp->pending_send));
len = dispatch[a->attr->type].encode(msrp, a, msg);
len = dispatch[a->attr->type].encode(msrp, a, msg,
sizeof(buffer) - total);
if (len < 0)
break;

View file

@ -64,7 +64,7 @@ static int process_vid(struct mvrp *mvrp, uint64_t now, uint8_t attr_type,
return mvrp_attr_event(mvrp, now, attr_type, event);
}
static int encode_vid(struct mvrp *mvrp, struct attr *a, void *m)
static int encode_vid(struct mvrp *mvrp, struct attr *a, void *m, size_t maxsize)
{
struct avb_packet_mvrp_msg *msg = m;
struct avb_packet_mrp_vector *v;
@ -73,6 +73,9 @@ static int encode_vid(struct mvrp *mvrp, struct attr *a, void *m)
uint8_t *ev;
size_t attr_list_length = sizeof(*v) + sizeof(*d) + sizeof(*f) + 1;
if (attr_list_length + sizeof(*msg) > maxsize)
return -ENOSPC;
msg->attribute_type = AVB_MVRP_ATTRIBUTE_TYPE_VID;
msg->attribute_length = sizeof(*d);
@ -102,7 +105,7 @@ static const struct {
const char *name;
int (*process) (struct mvrp *mvrp, uint64_t now, uint8_t attr_type,
const void *m, uint8_t event, uint8_t param, int num);
int (*encode) (struct mvrp *mvrp, struct attr *attr, void *m);
int (*encode) (struct mvrp *mvrp, struct attr *attr, void *m, size_t maxsize);
void (*notify) (struct mvrp *mvrp, uint64_t now, struct attr *attr, uint8_t notify);
} dispatch[] = {
[AVB_MVRP_ATTRIBUTE_TYPE_VID] = { "vid", process_vid, encode_vid, notify_vid },
@ -214,7 +217,7 @@ static void mvrp_event(void *data, uint64_t now, uint8_t event)
void *msg = SPA_PTROFF(buffer, sizeof(*p), void);
struct attr *a;
int len, count = 0;
size_t total = sizeof(*p) + 2;
size_t total = sizeof(*p) + sizeof(*f);
p->version = AVB_MRP_PROTOCOL_VERSION;
@ -227,7 +230,8 @@ static void mvrp_event(void *data, uint64_t now, uint8_t event)
pw_log_debug("send %s %s", dispatch[a->attr->type].name,
avb_mrp_send_name(a->attr->mrp->pending_send));
len = dispatch[a->attr->type].encode(mvrp, a, msg);
len = dispatch[a->attr->type].encode(mvrp, a, msg,
sizeof(buffer) - total);
if (len < 0)
break;