52 lines
2.0 KiB
Diff
52 lines
2.0 KiB
Diff
From 8f3230e5767d5938a70769249ed6f479d2925647 Mon Sep 17 00:00:00 2001
|
|
From: Dom <dominik@qreativelab.io>
|
|
Date: Mon, 4 May 2026 03:54:06 -0400
|
|
Subject: [PATCH] parser_lyb: fix integer overflow and OOM in
|
|
lyb_read_string/lyb_read_value
|
|
|
|
lyb_read_string: when str_len == UINT32_MAX, (str_len + 1) wraps to 0,
|
|
malloc(0) returns non-NULL, and the subsequent write to (*str)[UINT32_MAX]
|
|
causes a WRITE SEGV (memory corruption).
|
|
|
|
lyb_read_value: when lyb_size_bits == UINT32_MAX with VARIABLE_BYTES,
|
|
LYPLG_BITS2BYTES() produces ~4 GiB, causing calloc to attempt a 4 GiB
|
|
allocation which triggers OOM / DoS.
|
|
|
|
Both paths are reachable by supplying a malformed LYB input with
|
|
length field set to 0xFFFFFFFF.
|
|
|
|
Reported-by: Dominik Blain <dominik@qreativelab.io>, Cobalt AI
|
|
---
|
|
src/parser_lyb.c | 8 ++++++++
|
|
1 file changed, 8 insertions(+)
|
|
|
|
diff --git a/src/parser_lyb.c b/src/parser_lyb.c
|
|
index 788be9499..be9ec37b8 100644
|
|
--- a/src/parser_lyb.c
|
|
+++ b/src/parser_lyb.c
|
|
@@ -217,6 +217,9 @@ 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);
|
|
+
|
|
*str = malloc((len + 1) * sizeof **str);
|
|
LY_CHECK_ERR_RET(!*str, LOGMEM(lybctx->ctx), LY_EMEM);
|
|
|
|
@@ -281,6 +284,11 @@ lyb_read_term_value(const struct lysc_node_leaf *term, uint8_t **term_value, uin
|
|
*term_value_len = lyb_data_len;
|
|
}
|
|
|
|
+ /* *term_value_len + 1 can overflow when *term_value_len == UINT32_MAX,
|
|
+ * causing malloc to attempt a huge allocation (OOM / DoS) */
|
|
+ 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.52.0
|
|
|