libcoap: patch CVE-2026-29013

Details: https://nvd.nist.gov/vuln/detail/CVE-2026-29013

Debian[1] also identified this as a fix.
[1] https://security-tracker.debian.org/tracker/CVE-2026-29013

Signed-off-by: Ankur Tyagi <ankur.tyagi85@gmail.com>
Signed-off-by: Anuj Mittal <anuj.mittal@oss.qualcomm.com>
This commit is contained in:
Ankur Tyagi
2026-04-24 00:48:05 +12:00
committed by Anuj Mittal
parent c50a1edbcf
commit d91b26edec
2 changed files with 87 additions and 0 deletions
@@ -0,0 +1,86 @@
From 9e830709e98b0213c8806157ccae13df9d3fed74 Mon Sep 17 00:00:00 2001
From: Jon Shallow <supjps-libcoap@jpshallow.com>
Date: Tue, 24 Mar 2026 14:15:09 +0000
Subject: [PATCH] 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.
(cherry picked from commit b7847c4dbb0dbee7c90b09a673d4cae256f03718)
CVE: CVE-2026-29013
Upstream-Status: Backport [https://github.com/obgm/libcoap/commit/b7847c4dbb0dbee7c90b09a673d4cae256f03718]
Signed-off-by: Ankur Tyagi <ankur.tyagi85@gmail.com>
---
src/coap_cache.c | 3 ++-
src/coap_pdu.c | 11 +++++++++--
2 files changed, 11 insertions(+), 3 deletions(-)
diff --git a/src/coap_cache.c b/src/coap_cache.c
index 16931f56..e018604d 100644
--- a/src/coap_cache.c
+++ b/src/coap_cache.c
@@ -203,7 +203,8 @@ coap_new_cache_entry_lkd(coap_session_t *session, const coap_pdu_t *pdu,
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);
+ if (pdu->data)
+ entry->pdu->data = entry->pdu->token + (pdu->data - pdu->token);
}
}
entry->cache_key = coap_cache_derive_key(session, pdu, session_based);
diff --git a/src/coap_pdu.c b/src/coap_pdu.c
index 9394e6fe..2e06ccbc 100644
--- a/src/coap_pdu.c
+++ b/src/coap_pdu.c
@@ -280,10 +280,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;
@@ -314,8 +316,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;
}
@@ -629,7 +631,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);
@@ -9,6 +9,7 @@ LIC_FILES_CHKSUM = "file://LICENSE;md5=05d17535846895e23ea4c79b16a9e904"
SRC_URI = "git://github.com/obgm/libcoap.git;branch=release-4.3.5-patches;protocol=https;tag=v${PV} \
file://run-ptest \
file://CVE-2026-29013.patch \
"
SRCREV = "e3fdcdcfbd1588754fe9dd4b754ac9397260f0f9"