coap_resource.c: harden coap_print_wellknown_lkd() against short attribute values

In the "match attribute" branch of coap_print_wellknown_lkd(), an
attribute value shorter than 2 bytes (e.g. a lone " registered via
coap_add_attr()) causes attr->value->s[0] == '"' to read past the
value, and unquoted_val.length -= 2 to underflow the size_t length
to SIZE_MAX. The resulting bogus coap_str_const_t is then passed to
match(), which dereferences memory far outside the original buffer.

Guard the quote-check on length >= 2 before reading s[0], mirroring
the length && ... guard already used a few lines above for
query_pattern (added in #1977) and the trailing-'*' guard next to
it.

Reproduced with a standalone harness placing a 1-byte attribute
value at the end of a guard-paged region: pre-fix, unquoted_val.length
becomes SIZE_MAX and match() crashes on the guard page; post-fix,
length stays at the original value (no underflow) and match() safely
short-circuits. A normal quoted value ("foo", 5 bytes) still strips
to foo (3 bytes) unchanged, confirming no regression.
This commit is contained in:
94xhn authored and Jon Shallow committed 2026-07-17 15:24:27 +01:00
1 parent 1122bf9fb9
commit 09e91a2e5c
1 file changed
+2 -1
+2 -1
View File
@@ -213,7 +213,8 @@ coap_print_wellknown_lkd(coap_context_t *context, unsigned char *buf,
if (!attr || !attr->value)
continue;
unquoted_val = *attr->value;
if (attr->value->s[0] == '"') { /* if attribute has a quoted value, remove double quotes */
/* if attribute has a quoted value, remove double quotes */
if (attr->value->length >= 2 && attr->value->s[0] == '"') {
unquoted_val.length -= 2;
unquoted_val.s += 1;
}