mirror of
https://github.com/openembedded/meta-openembedded.git
synced 2026-07-27 07:57:27 +00:00
libyang: Fix CVE-2026-41401 and CVE-2026-44673
CVE-2026-41401: Fix incorrect metadata list pointer update in lyd_parse_set_data_flags() when freeing the head metadata entry. Without this fix, crafted YANG XML documents with specific metadata ordering can trigger invalid pointer states in the metadata linked list. CVE-2026-44673: Fix integer overflow and OOM in the LYB binary parser. lyb_read_string() wraps len + 1 to 0 when len == UINT64_MAX, and lyb_read_term_value() truncates uint64_t to uint32_t causing undersized allocation. Both paths are reachable via malformed LYB input with crafted length fields. Signed-off-by: Yunseong Kim <yunseong.kim@est.tech> Signed-off-by: Anuj Mittal <anuj.mittal@oss.qualcomm.com>
This commit is contained in:
committed by
Anuj Mittal
parent
1f99172329
commit
c8dc986a39
@@ -0,0 +1,49 @@
|
||||
From 54c3276d871023da266d4ed3ceaee7e8d71d0b04 Mon Sep 17 00:00:00 2001
|
||||
From: Michal Vasko <mvasko@cesnet.cz>
|
||||
Date: Thu, 26 Mar 2026 08:33:44 +0100
|
||||
Subject: [PATCH] parser common BUGFIX invalid metadata removal
|
||||
|
||||
Fix incorrect metadata list pointer update in lyd_parse_set_data_flags()
|
||||
when freeing the head metadata entry via a separate meta pointer. The
|
||||
condition must verify that meta2 is actually the head of *meta before
|
||||
updating the list head pointer, and must use meta2->next (which is
|
||||
saved before the free) rather than (*meta)->next.
|
||||
|
||||
Without this fix, crafted YANG XML documents with specific metadata
|
||||
ordering (e.g., operation + default metadata) can trigger invalid
|
||||
pointer states in the metadata linked list.
|
||||
|
||||
CVE: CVE-2026-41401
|
||||
Upstream-Status: Backport [https://github.com/CESNET/libyang/commit/54c3276d871023da266d4ed3ceaee7e8d71d0b04]
|
||||
|
||||
Backport Changes:
|
||||
- Adapted for v2.1.148 where the function is named
|
||||
lyd_parse_set_data_flags (renamed to lyd_parser_set_data_flags in
|
||||
newer versions).
|
||||
- The fix logic is identical: change the else-if condition to also
|
||||
check (meta2 == *meta) and use meta2->next instead of (*meta)->next.
|
||||
|
||||
(cherry picked from commit 54c3276d871023da266d4ed3ceaee7e8d71d0b04)
|
||||
Signed-off-by: Yunseong Kim <yunseong.kim@est.tech>
|
||||
---
|
||||
src/parser_common.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/src/parser_common.c b/src/parser_common.c
|
||||
index 32152759e..f8a3b1c01 100644
|
||||
--- a/src/parser_common.c
|
||||
+++ b/src/parser_common.c
|
||||
@@ -394,8 +394,8 @@ lyd_parse_set_data_flags(struct lyd_node *node, struct lyd_meta **meta, struct l
|
||||
/* delete the metadata */
|
||||
if (prev_meta) {
|
||||
prev_meta->next = meta2->next;
|
||||
- } else if (meta != &node->meta) {
|
||||
- *meta = (*meta)->next;
|
||||
+ } else if ((meta != &node->meta) && (meta2 == *meta)) {
|
||||
+ *meta = meta2->next;
|
||||
}
|
||||
lyd_free_meta_single(meta2);
|
||||
|
||||
--
|
||||
2.43.0
|
||||
|
||||
@@ -0,0 +1,66 @@
|
||||
From 48672b289e2e4c6773712c3ee0abae6b7fffe1f3 Mon Sep 17 00:00:00 2001
|
||||
From: dominik blain <dominik@qreativelab.io>
|
||||
Date: Wed, 6 May 2026 03:03:14 -0400
|
||||
Subject: [PATCH] parser lyb BUGFIX integer overflow and OOM (#2513)
|
||||
|
||||
lyb_read_string: when len == UINT64_MAX, (len + 1) wraps to 0,
|
||||
malloc(0) returns non-NULL, and the subsequent write to (*str)[len]
|
||||
causes a WRITE SEGV (memory corruption).
|
||||
|
||||
lyb_read_term_value: when term_value_len is large, truncation from
|
||||
uint64_t to uint32_t allocated_size causes undersized allocation
|
||||
followed by out-of-bounds write.
|
||||
|
||||
Both paths are reachable by supplying a malformed LYB input with
|
||||
crafted length fields.
|
||||
|
||||
Reported-by: Dominik Blain <dominik@qreativelab.io>, Cobalt AI
|
||||
|
||||
CVE: CVE-2026-44673
|
||||
Upstream-Status: Backport [https://github.com/CESNET/libyang/commit/48672b289e2e4c6773712c3ee0abae6b7fffe1f3]
|
||||
|
||||
Backport Changes:
|
||||
- Adapted for v2.1.148 code structure where lyb_read_string uses
|
||||
uint64_t len (not uint32_t str_len) and lyb_read_term_value uses
|
||||
uint32_t allocated_size with uint64_t term_value_len (not
|
||||
lyb_read_value with val_size_bits).
|
||||
- Added overflow check for len in lyb_read_string to prevent wrap to 0.
|
||||
- Added overflow check for term_value_len in lyb_read_term_value to
|
||||
prevent uint32_t truncation in allocated_size.
|
||||
|
||||
(cherry picked from commit 48672b289e2e4c6773712c3ee0abae6b7fffe1f3)
|
||||
Signed-off-by: Yunseong Kim <yunseong.kim@est.tech>
|
||||
---
|
||||
src/parser_lyb.c | 10 ++++++++++
|
||||
1 file changed, 10 insertions(+)
|
||||
|
||||
diff --git a/src/parser_lyb.c b/src/parser_lyb.c
|
||||
index 788be9499..c1cbfc805 100644
|
||||
--- a/src/parser_lyb.c
|
||||
+++ b/src/parser_lyb.c
|
||||
@@ -217,6 +217,12 @@ lyb_read_string(char **str, uint8_t len_size, struct lylyb_ctx *lybctx)
|
||||
|
||||
lyb_read_number(&len, sizeof len, len_size, lybctx);
|
||||
|
||||
+ /* len + 1 wraps to 0 when len == UINT64_MAX, causing malloc(0) followed by an out-of-bounds write */
|
||||
+ LY_CHECK_ERR_RET(len == UINT64_MAX,
|
||||
+ LOGERR(lybctx->ctx, LY_EINVAL, "LYB string length overflow."), LY_EINVAL);
|
||||
+ LY_CHECK_ERR_RET(len >= SIZE_MAX,
|
||||
+ LOGERR(lybctx->ctx, LY_EINVAL, "LYB string length overflow."), LY_EINVAL);
|
||||
+
|
||||
*str = malloc((len + 1) * sizeof **str);
|
||||
LY_CHECK_ERR_RET(!*str, LOGMEM(lybctx->ctx), LY_EMEM);
|
||||
|
||||
@@ -281,6 +287,10 @@ lyb_read_term_value(const struct lysc_node_leaf *term, uint8_t **term_value, uin
|
||||
*term_value_len = lyb_data_len;
|
||||
}
|
||||
|
||||
+ /* Prevent uint32_t truncation: if term_value_len exceeds UINT32_MAX - 1, allocated_size overflows */
|
||||
+ LY_CHECK_ERR_RET(*term_value_len >= UINT32_MAX,
|
||||
+ LOGERR(lybctx->ctx, LY_EINVAL, "LYB value size overflow."), LY_EINVAL);
|
||||
+
|
||||
/* Allocate memory. */
|
||||
allocated_size = *term_value_len + 1;
|
||||
*term_value = malloc(allocated_size * sizeof **term_value);
|
||||
--
|
||||
2.43.0
|
||||
@@ -10,6 +10,8 @@ SRCREV = "fc4dbd923e044006c93df020590a1e5a8656c09e"
|
||||
|
||||
SRC_URI = "git://github.com/CESNET/libyang.git;branch=master;protocol=https \
|
||||
file://0001-test_context-skip-test-case-test_searchdirs.patch \
|
||||
file://CVE-2026-41401.patch \
|
||||
file://CVE-2026-44673.patch \
|
||||
file://run-ptest \
|
||||
"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user