Resolves: #1965253 - CVE-2021-28902 libyang: NULL pointer dereference in read_yin_container()

Resolves: #1965255 - CVE-2021-28903 libyang: recursive call to lyxml_parse_mem() lead to crash
This commit is contained in:
Michal Ruprich 2021-07-14 16:24:29 +02:00
parent 0d5064a914
commit e62e7dca15
3 changed files with 146 additions and 3 deletions

View File

@ -0,0 +1,66 @@
From a3917d95d516e3de267d3cfa5d4d3715a90e8777 Mon Sep 17 00:00:00 2001
From: Michal Vasko <mvasko@cesnet.cz>
Date: Mon, 8 Mar 2021 14:08:05 +0100
Subject: [PATCH] yin parser BUGFIX invalid memory access
... in case there were some unresolved
extensions.
Fixes #1454
Fixes #1455
---
src/parser_yin.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/src/parser_yin.c b/src/parser_yin.c
index 275991644..256325415 100644
--- a/src/parser_yin.c
+++ b/src/parser_yin.c
@@ -4572,7 +4572,7 @@ read_yin_anydata(struct lys_module *module, struct lys_node *parent, struct lyxm
for (r = 0; r < retval->ext_size; ++r) {
/* set flag, which represent LYEXT_OPT_VALID */
- if (retval->ext[r]->flags & LYEXT_OPT_VALID) {
+ if (retval->ext[r] && (retval->ext[r]->flags & LYEXT_OPT_VALID)) {
retval->flags |= LYS_VALID_EXT;
break;
}
@@ -4794,7 +4794,7 @@ read_yin_leaf(struct lys_module *module, struct lys_node *parent, struct lyxml_e
for (r = 0; r < retval->ext_size; ++r) {
/* set flag, which represent LYEXT_OPT_VALID */
- if (retval->ext[r]->flags & LYEXT_OPT_VALID) {
+ if (retval->ext[r] && (retval->ext[r]->flags & LYEXT_OPT_VALID)) {
retval->flags |= LYS_VALID_EXT;
break;
}
@@ -5108,7 +5108,7 @@ read_yin_leaflist(struct lys_module *module, struct lys_node *parent, struct lyx
for (r = 0; r < retval->ext_size; ++r) {
/* set flag, which represent LYEXT_OPT_VALID */
- if (retval->ext[r]->flags & LYEXT_OPT_VALID) {
+ if (retval->ext[r] && (retval->ext[r]->flags & LYEXT_OPT_VALID)) {
retval->flags |= LYS_VALID_EXT;
break;
}
@@ -5477,7 +5477,7 @@ read_yin_list(struct lys_module *module, struct lys_node *parent, struct lyxml_e
for (r = 0; r < retval->ext_size; ++r) {
/* set flag, which represent LYEXT_OPT_VALID */
- if (retval->ext[r]->flags & LYEXT_OPT_VALID) {
+ if (retval->ext[r] && (retval->ext[r]->flags & LYEXT_OPT_VALID)) {
retval->flags |= LYS_VALID_EXT;
if (retval->ext[r]->flags & LYEXT_OPT_VALID_SUBTREE) {
retval->flags |= LYS_VALID_EXT_SUBTREE;
@@ -5701,8 +5701,9 @@ read_yin_container(struct lys_module *module, struct lys_node *parent, struct ly
}
for (r = 0; r < retval->ext_size; ++r) {
- /* set flag, which represent LYEXT_OPT_VALID */
- if (retval->ext[r]->flags & LYEXT_OPT_VALID) {
+ /* extension instance may not yet be resolved */
+ if (retval->ext[r] && (retval->ext[r]->flags & LYEXT_OPT_VALID)) {
+ /* set flag, which represent LYEXT_OPT_VALID */
retval->flags |= LYS_VALID_EXT;
if (retval->ext[r]->flags & LYEXT_OPT_VALID_SUBTREE) {
retval->flags |= LYS_VALID_EXT_SUBTREE;

View File

@ -0,0 +1,70 @@
From 298b30ea4ebee137226acf9bb38678bd82704582 Mon Sep 17 00:00:00 2001
From: Michal Vasko <mvasko@cesnet.cz>
Date: Mon, 8 Mar 2021 14:32:58 +0100
Subject: [PATCH] common FEATURE add a hard limit for recursion
Fixes #1453
---
src/common.h.in | 3 +++
src/xml.c | 12 +++++++++---
2 files changed, 12 insertions(+), 3 deletions(-)
diff --git a/src/common.h.in b/src/common.h.in
index a5bf2b038..624beba9f 100644
--- a/src/common.h.in
+++ b/src/common.h.in
@@ -53,6 +53,9 @@
/* how many bytes add when enlarging buffers */
#define LY_BUF_STEP 128
+/* hard limit on recursion for cases with theoretical unlimited recursion */
+#define LY_RECURSION_LIMIT 10000
+
/* internal logging options */
enum int_log_opts {
ILO_LOG = 0, /* log normally */
diff --git a/src/xml.c b/src/xml.c
index 1bc4fdfa5..7e4760976 100644
--- a/src/xml.c
+++ b/src/xml.c
@@ -943,7 +943,8 @@ parse_attr(struct ly_ctx *ctx, const char *data, unsigned int *len, struct lyxml
/* logs directly */
struct lyxml_elem *
-lyxml_parse_elem(struct ly_ctx *ctx, const char *data, unsigned int *len, struct lyxml_elem *parent, int options)
+lyxml_parse_elem(struct ly_ctx *ctx, const char *data, unsigned int *len, struct lyxml_elem *parent, int options,
+ int bt_count)
{
const char *c = data, *start, *e;
const char *lws; /* leading white space for handling mixed content */
@@ -958,6 +959,11 @@ lyxml_parse_elem(struct ly_ctx *ctx, const char *data, unsigned int *len, struct
*len = 0;
+ if (bt_count > LY_RECURSION_LIMIT) {
+ LOGVAL(ctx, LYE_XML_INVAL, LY_VLOG_NONE, NULL, "Recursion limit %d reached", LY_RECURSION_LIMIT);
+ return NULL;
+ }
+
if (*c != '<') {
return NULL;
}
@@ -1141,7 +1147,7 @@ lyxml_parse_elem(struct ly_ctx *ctx, const char *data, unsigned int *len, struct
lyxml_add_child(ctx, elem, child);
elem->flags |= LYXML_ELEM_MIXED;
}
- child = lyxml_parse_elem(ctx, c, &size, elem, options);
+ child = lyxml_parse_elem(ctx, c, &size, elem, options, bt_count + 1);
if (!child) {
goto error;
}
@@ -1295,7 +1301,7 @@ lyxml_parse_mem(struct ly_ctx *ctx, const char *data, int options)
}
}
- root = lyxml_parse_elem(ctx, c, &len, NULL, options);
+ root = lyxml_parse_elem(ctx, c, &len, NULL, options, 0);
if (!root) {
goto error;
} else if (!first) {

View File

@ -8,13 +8,15 @@
Name: libyang
Version: 1.0.225
Release: 2%{?dist}
Release: 3%{?dist}
Summary: YANG data modeling language library
Url: https://github.com/CESNET/libyang
Source: %{url}/archive/v%{version}.tar.gz
License: BSD
Patch0: libyang-1.0.184-doc.patch
Patch1: libyang-1.0.225-CVE-2021-28902.patch
Patch2: libyang-1.0.225-CVE-2021-28903.patch
Requires: pcre
BuildRequires: cmake
@ -29,7 +31,8 @@ BuildRequires: python3-devel
BuildRequires: flex
BuildRequires: bison
BuildRequires: graphviz
BuildRequires: make
BuildRequires: make
BuildRequires: git-core
%package devel
Summary: Development files for libyang
@ -75,7 +78,7 @@ Libyang is YANG data modeling language parser and toolkit
written (and providing API) in C.
%prep
%autosetup
%autosetup -S git
%build
%cmake \
@ -138,6 +141,10 @@ cp -r doc/html %{buildroot}/%{_docdir}/libyang/html
%{python3_sitearch}/__pycache__/yang*
%changelog
* Wed Jun 30 2021 Michal Ruprich <mruprich@redhat.com> - 1.0.225-3
- Resolves: #1965253 - CVE-2021-28902 libyang: NULL pointer dereference in read_yin_container()
- Resolves: #1965255 - CVE-2021-28903 libyang: recursive call to lyxml_parse_mem() lead to crash
* Fri Apr 16 2021 Mohan Boddu <mboddu@redhat.com> - 1.0.225-2
- Rebuilt for RHEL 9 BETA on Apr 15th 2021. Related: rhbz#1947937