From 45a4d682ef1ffbf6a77550663bf7bc1a0da121b6 Mon Sep 17 00:00:00 2001 From: Shrushti P K Date: Fri, 16 Oct 2026 21:23:45 +0530 Subject: [PATCH] logger: validate uids dictionary offset and uid entry bounds convert() copies the uuid dictionary header from the .ldc file into uids_dict as is and always loads the uuid entries right after it, but get_uuid_entry(), get_uuid_key(), dump_ldc_info() and get_uuid_by_name() all locate the entries through the header's data_offset field, which is never checked. smex always writes sizeof(struct snd_sof_uids_header) there; any other value makes every dictionary lookup read outside of the allocation. Reject it at load time. get_component_name() also bounds the uid taken from the trace stream with a bare ">=" check, so a uid pointing into the last bytes of the section passes and the entry name is read past the end of the buffer. Require a full sof_uuid_entry to fit in the section, comparing the offset from base_address against the remaining length so the check can't wrap on hosts with a 32-bit size_t. Signed-off-by: Shrushti P K --- tools/logger/convert.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/tools/logger/convert.c b/tools/logger/convert.c index 834ee5a1b243..d41563297135 100644 --- a/tools/logger/convert.c +++ b/tools/logger/convert.c @@ -420,8 +420,9 @@ static const char *get_component_name(uint32_t trace_class, uint32_t uid_ptr) /* if uid_ptr is non-zero, find name in the ldc file */ if (uid_ptr) { if (uid_ptr < uids_dict->base_address || - uid_ptr >= uids_dict->base_address + - uids_dict->data_length) + uids_dict->data_length < sizeof(struct sof_uuid_entry) || + uid_ptr - uids_dict->base_address > + uids_dict->data_length - sizeof(struct sof_uuid_entry)) return ""; uid_entry = get_uuid_entry(uid_ptr); return uid_entry->name; @@ -1127,6 +1128,16 @@ int convert(void) log_err("invalid uuid section signature.\n"); return -EINVAL; } + /* + * The uuid entries are always read right after the header below, so + * any other data_offset would make every dictionary lookup through + * uids_dict->data_offset point outside of the allocation. + */ + if (uids_hdr.data_offset != sizeof(uids_hdr)) { + log_err("invalid uuid section data offset %u.\n", + uids_hdr.data_offset); + return -EINVAL; + } config->uids_dict = calloc(1, sizeof(uids_hdr) + uids_hdr.data_length); if (!config->uids_dict) { log_err("failed to alloc memory for uuids.\n");