sanitizer: Fix reported issues

coap_new_cache_entry() does not correctly check for no PDU data when called
with COAP_CACHE_RECORD_PDU. No current libcoap code (examples and library)
call coap_new_cache_entry() with COAP_CACHE_RECORD_PDU set.

Internal function coap_pdu_resize() can be used to reduce a PDU size,
creating current options confusion.  Fix is not to reduce PDU if new
size is smaller than the current used size. No current libcoap code calls
coap_pdu_resize() to reduce the size.

If there is an issue with the PDU options where the maximum used option
value is larger than the last defined option value, an assert() is triggered.

All of the coap_*_option() functions correctly manage pdu->max_opt, but
this issue could occur if coap_pdu_resize() was called to reduce the PDU size
below that of pdu->used_size.
This commit is contained in:
Jon Shallow authored and Jon Shallow committed 2026-03-24 18:35:31 +00:00
1 parent 84560ef825
commit a307ef9467
2 files changed
+10 -15

No files matched your search

+1 -13
View File
@@ -192,19 +192,7 @@ coap_new_cache_entry_lkd(coap_session_t *session, const coap_pdu_t *pdu,
memset(entry, 0, sizeof(coap_cache_entry_t));
entry->session = session;
if (record_pdu == COAP_CACHE_RECORD_PDU) {
entry->pdu = coap_pdu_init(pdu->type, pdu->code, pdu->mid, pdu->alloc_size);
if (entry->pdu) {
if (!coap_pdu_resize(entry->pdu, pdu->alloc_size)) {
coap_delete_pdu_lkd(entry->pdu);
coap_free_type(COAP_CACHE_ENTRY, entry);
return NULL;
}
/* Need to get the appropriate data across */
memcpy(entry->pdu, pdu, offsetof(coap_pdu_t, token));
memcpy(entry->pdu->token, pdu->token, pdu->used_size);
/* And adjust all the pointers etc. */
entry->pdu->data = entry->pdu->token + (pdu->data - pdu->token);
}
entry->pdu = coap_const_pdu_reference_lkd(pdu);
}
entry->cache_key = coap_cache_derive_key(session, pdu, session_based);
if (!entry->cache_key) {
+9 -2
View File
@@ -306,10 +306,12 @@ fail:
int
coap_pdu_resize(coap_pdu_t *pdu, size_t new_size) {
if (new_size > pdu->alloc_size) {
/* Expanding the PDU usage */
#if !defined(WITH_LWIP)
uint8_t *new_hdr;
size_t offset;
#endif
if (pdu->max_size && new_size > pdu->max_size) {
coap_log_warn("coap_pdu_resize: pdu too big\n");
return 0;
@@ -340,8 +342,8 @@ coap_pdu_resize(coap_pdu_t *pdu, size_t new_size) {
else
pdu->actual_token.s = &pdu->token[2];
#endif
pdu->alloc_size = new_size;
}
pdu->alloc_size = new_size;
return 1;
}
@@ -658,7 +660,12 @@ coap_insert_option(coap_pdu_t *pdu, coap_option_num_t number, size_t len,
}
prev_number = opt_iter.number;
}
assert(option != NULL);
if (option == NULL) {
/* Code is broken somewhere */
coap_log_warn("coap_insert_option: Broken max_opt\n");
return 0;
}
/* size of option inc header to insert */
shift = coap_opt_encode_size(number - prev_number, len);