From 7dacdc8cc8586403e644f58408a6ea0a399e6348 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Mon, 4 May 2026 10:47:52 +0200 Subject: [PATCH] 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. --- src/modules/module-avb/msrp.c | 22 ++++++++++++++++------ src/modules/module-avb/mvrp.c | 12 ++++++++---- 2 files changed, 24 insertions(+), 10 deletions(-) diff --git a/src/modules/module-avb/msrp.c b/src/modules/module-avb/msrp.c index f03c99591..a47bef3b9 100644 --- a/src/modules/module-avb/msrp.c +++ b/src/modules/module-avb/msrp.c @@ -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; diff --git a/src/modules/module-avb/mvrp.c b/src/modules/module-avb/mvrp.c index fb910d83b..3e521fa21 100644 --- a/src/modules/module-avb/mvrp.c +++ b/src/modules/module-avb/mvrp.c @@ -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;