This is an automated email from the ASF dual-hosted git repository.

sjanc pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mynewt-core.git

commit 49b70dab2d630c772344a4db80c8306dece64dd2
Author: Szymon Janc <[email protected]>
AuthorDate: Wed Oct 21 00:43:20 2026 +0200

    sys/log: Fix use after free in log_append_mbuf_typed_no_free
    
    Header pointer was taken before os_mbuf_pullup() calls. If pullup had
    to move data to a new mbuf it freed the old one and log_append_prepare()
    then wrote entry header into freed memory.
    
    Header length used for the second pullup was also read from header
    flags before log_append_prepare() sets them, i.e. from uninitialized
    padding provided by caller. Pull up whole LOG_HDR_SIZE padding instead,
    which caller is required to provide, and get header pointer after it.
    
    Found by sys/log/full/selftest/align1, fcb2_align1 and perlogidx tests
    failing with OS_DEBUG_MODE enabled (mempool poison check).
    
    Assisted-by: Claude:claude-opus-5-5
---
 sys/log/full/src/log.c | 23 +++++++----------------
 1 file changed, 7 insertions(+), 16 deletions(-)

diff --git a/sys/log/full/src/log.c b/sys/log/full/src/log.c
index 10af4fe86..7befec2c5 100644
--- a/sys/log/full/src/log.c
+++ b/sys/log/full/src/log.c
@@ -749,7 +749,6 @@ log_append_mbuf_typed_no_free(struct log *log, uint8_t 
module, uint8_t level,
     struct log_entry_hdr *hdr;
     struct os_mbuf *om;
     uint16_t len;
-    uint16_t hdr_len;
     int rc;
 
     /* Remove a layer of indirection for convenience. */
@@ -761,26 +760,18 @@ log_append_mbuf_typed_no_free(struct log *log, uint8_t 
module, uint8_t level,
         goto err;
     }
 
-    hdr = (struct log_entry_hdr *)om->om_data;
-
     /*
-     * We do a pull up twice, once so that the base header is
-     * contiguous, so that we read the flags correctly, second
-     * time is so that we account for the image hash as well.
+     * Make the header padding contiguous. Header length can't be read from
+     * the header flags here since those are set by log_append_prepare().
      */
-    om = os_mbuf_pullup(om, LOG_BASE_ENTRY_HDR_SIZE);
+    om = os_mbuf_pullup(om, LOG_HDR_SIZE);
     if (!om) {
         rc = -1;
         goto err;
     }
 
-    hdr_len = log_hdr_len(hdr);
-
-    om = os_mbuf_pullup(om, hdr_len);
-    if (!om) {
-        rc = -1;
-        goto err;
-    }
+    /* Pullup may have moved the header to a new mbuf. */
+    hdr = (struct log_entry_hdr *)om->om_data;
 
     /*
      * Check that the log body length is less than the maximum entry. This code
@@ -790,8 +781,8 @@ log_append_mbuf_typed_no_free(struct log *log, uint8_t 
module, uint8_t level,
      * maximum entry length was checked.
      */
     len = os_mbuf_len(om);
-    if (len > hdr_len) {
-        rc = log_chk_max_entry_len(log, len - hdr_len);
+    if (len > LOG_HDR_SIZE) {
+        rc = log_chk_max_entry_len(log, len - LOG_HDR_SIZE);
         if (rc != OS_OK) {
             goto drop;
         }

Reply via email to