diff --git a/CVE-2021-28905.patch b/CVE-2021-28905.patch new file mode 100644 index 0000000000000000000000000000000000000000..89e620720c72eb500938d83329c6badea46620f5 --- /dev/null +++ b/CVE-2021-28905.patch @@ -0,0 +1,263 @@ +From 5ce30801f9ccc372bbe9b7c98bb5324b15fb010a Mon Sep 17 00:00:00 2001 +From: Michal Vasko +Date: Mon, 8 Mar 2021 09:34:04 +0100 +Subject: [PATCH] schema tree BUGFIX freeing nodes with no module set + +Context must be passed explicitly for these cases. +Fixes #1452 +--- + src/parser_yin.c | 24 ++++++++++++------------ + src/resolve.c | 2 +- + src/tree_internal.h | 4 +++- + src/tree_schema.c | 27 +++++++++++---------------- + 4 files changed, 27 insertions(+), 30 deletions(-) + +diff --git a/src/parser_yin.c b/src/parser_yin.c +index d545a6d26..275991644 100644 +--- a/src/parser_yin.c ++++ b/src/parser_yin.c +@@ -4213,7 +4213,7 @@ read_yin_case(struct lys_module *module, struct lys_node *parent, struct lyxml_e + while (root.child) { + lyxml_free(ctx, root.child); + } +- lys_node_free(retval, NULL, 0); ++ lys_node_free(ctx, retval, NULL, 0); + + return NULL; + } +@@ -4420,7 +4420,7 @@ read_yin_choice(struct lys_module *module, struct lys_node *parent, struct lyxml + + error: + lyxml_free(ctx, dflt); +- lys_node_free(retval, NULL, 0); ++ lys_node_free(ctx, retval, NULL, 0); + return NULL; + } + +@@ -4581,7 +4581,7 @@ read_yin_anydata(struct lys_module *module, struct lys_node *parent, struct lyxm + return retval; + + error: +- lys_node_free(retval, NULL, 0); ++ lys_node_free(ctx, retval, NULL, 0); + return NULL; + } + +@@ -4803,7 +4803,7 @@ read_yin_leaf(struct lys_module *module, struct lys_node *parent, struct lyxml_e + return retval; + + error: +- lys_node_free(retval, NULL, 0); ++ lys_node_free(ctx, retval, NULL, 0); + return NULL; + } + +@@ -5117,7 +5117,7 @@ read_yin_leaflist(struct lys_module *module, struct lys_node *parent, struct lyx + return retval; + + error: +- lys_node_free(retval, NULL, 0); ++ lys_node_free(ctx, retval, NULL, 0); + return NULL; + } + +@@ -5490,7 +5490,7 @@ read_yin_list(struct lys_module *module, struct lys_node *parent, struct lyxml_e + + error: + +- lys_node_free(retval, NULL, 0); ++ lys_node_free(ctx, retval, NULL, 0); + while (root.child) { + lyxml_free(ctx, root.child); + } +@@ -5714,7 +5714,7 @@ read_yin_container(struct lys_module *module, struct lys_node *parent, struct ly + return retval; + + error: +- lys_node_free(retval, NULL, 0); ++ lys_node_free(ctx, retval, NULL, 0); + while (root.child) { + lyxml_free(ctx, root.child); + } +@@ -5859,7 +5859,7 @@ read_yin_grouping(struct lys_module *module, struct lys_node *parent, struct lyx + return retval; + + error: +- lys_node_free(retval, NULL, 0); ++ lys_node_free(ctx, retval, NULL, 0); + while (root.child) { + lyxml_free(ctx, root.child); + } +@@ -6035,7 +6035,7 @@ read_yin_input_output(struct lys_module *module, struct lys_node *parent, struct + return retval; + + error: +- lys_node_free(retval, NULL, 0); ++ lys_node_free(ctx, retval, NULL, 0); + while (root.child) { + lyxml_free(ctx, root.child); + } +@@ -6216,7 +6216,7 @@ read_yin_notif(struct lys_module *module, struct lys_node *parent, struct lyxml_ + return retval; + + error: +- lys_node_free(retval, NULL, 0); ++ lys_node_free(ctx, retval, NULL, 0); + while (root.child) { + lyxml_free(ctx, root.child); + } +@@ -6368,7 +6368,7 @@ read_yin_rpc_action(struct lys_module *module, struct lys_node *parent, struct l + return retval; + + error: +- lys_node_free(retval, NULL, 0); ++ lys_node_free(ctx, retval, NULL, 0); + while (root.child) { + lyxml_free(ctx, root.child); + } +@@ -6522,7 +6522,7 @@ read_yin_uses(struct lys_module *module, struct lys_node *parent, struct lyxml_e + return retval; + + error: +- lys_node_free(retval, NULL, 0); ++ lys_node_free(ctx, retval, NULL, 0); + return NULL; + } + +diff --git a/src/resolve.c b/src/resolve.c +index 21293ebc2..29862187f 100644 +--- a/src/resolve.c ++++ b/src/resolve.c +@@ -5654,7 +5654,7 @@ resolve_uses(struct lys_node_uses *uses, struct unres_schema *unres) + + fail: + LY_TREE_FOR_SAFE(uses->child, next, iter) { +- lys_node_free(iter, NULL, 0); ++ lys_node_free(ctx, iter, NULL, 0); + } + free(refine_nodes); + return -1; +diff --git a/src/tree_internal.h b/src/tree_internal.h +index 497c62c4d..36e94f5c5 100644 +--- a/src/tree_internal.h ++++ b/src/tree_internal.h +@@ -368,12 +368,14 @@ void lys_node_unlink(struct lys_node *node); + /** + * @brief Free the schema node structure, includes unlinking it from the tree + * ++ * @param[in] ctx libang context to use, @p node may not have it filled (in groupings, for example). + * @param[in] node Schema tree node to free. Do not use the pointer after calling this function. + * @param[in] private_destructor Optional destructor function for private objects assigned + * to the nodes via lys_set_private(). If NULL, the private objects are not freed by libyang. + * @param[in] shallow Whether to do a shallow free only (on a shallow copy of a node). + */ +-void lys_node_free(struct lys_node *node, void (*private_destructor)(const struct lys_node *node, void *priv), int shallow); ++void lys_node_free(struct ly_ctx *ctx, struct lys_node *node, ++ void (*private_destructor)(const struct lys_node *node, void *priv), int shallow); + + /** + * @brief Free (and unlink it from the context) the specified schema. +diff --git a/src/tree_schema.c b/src/tree_schema.c +index 43b19039f..fb4c85f3f 100644 +--- a/src/tree_schema.c ++++ b/src/tree_schema.c +@@ -942,7 +942,7 @@ lys_node_addchild(struct lys_node *parent, struct lys_module *module, struct lys + iter->next = NULL; + iter->prev = iter; + iter->parent = NULL; +- lys_node_free(iter, NULL, 0); ++ lys_node_free(ctx, iter, NULL, 0); + } else { + if (shortcase) { + /* create the implicit case to allow it to serve as a target of the augments, +@@ -2464,7 +2464,7 @@ lys_augment_free(struct ly_ctx *ctx, struct lys_node_augment *aug, + /* children from a resolved augment are freed under the target node */ + if (!aug->target || (aug->flags & LYS_NOTAPPLIED)) { + LY_TREE_FOR_SAFE(aug->child, next, sub) { +- lys_node_free(sub, private_destructor, 0); ++ lys_node_free(ctx, sub, private_destructor, 0); + } + } + +@@ -2722,11 +2722,11 @@ lys_deviation_free(struct lys_module *module, struct lys_deviation *dev, + + LY_TREE_DFS_END(dev->orig_node, next, elem); + } +- lys_node_free(dev->orig_node, NULL, 0); ++ lys_node_free(ctx, dev->orig_node, NULL, 0); + } else { + /* it's just a shallow copy, freeing one node */ + dev->orig_node->module = module; +- lys_node_free(dev->orig_node, NULL, 1); ++ lys_node_free(ctx, dev->orig_node, NULL, 1); + } + } + +@@ -2798,20 +2798,15 @@ lys_uses_free(struct ly_ctx *ctx, struct lys_node_uses *uses, + } + + void +-lys_node_free(struct lys_node *node, void (*private_destructor)(const struct lys_node *node, void *priv), int shallow) ++lys_node_free(struct ly_ctx *ctx, struct lys_node *node, ++ void (*private_destructor)(const struct lys_node *node, void *priv), int shallow) + { +- struct ly_ctx *ctx; + struct lys_node *sub, *next; + + if (!node) { + return; + } + +- assert(node->module); +- assert(node->module->ctx); +- +- ctx = node->module->ctx; +- + /* remove private object */ + if (node->priv && private_destructor) { + private_destructor(node, node->priv); +@@ -2827,7 +2822,7 @@ lys_node_free(struct lys_node *node, void (*private_destructor)(const struct lys + + if (!shallow && !(node->nodetype & (LYS_LEAF | LYS_LEAFLIST))) { + LY_TREE_FOR_SAFE(node->child, next, sub) { +- lys_node_free(sub, private_destructor, 0); ++ lys_node_free(ctx, sub, private_destructor, 0); + } + } + +@@ -2942,7 +2937,7 @@ module_free_common(struct lys_module *module, void (*private_destructor)(const s + * are placed in the main module altogether */ + if (!module->type) { + LY_TREE_FOR_SAFE(module->data, next, iter) { +- lys_node_free(iter, private_destructor, 0); ++ lys_node_free(ctx, iter, private_destructor, 0); + } + } + +@@ -3507,7 +3502,7 @@ lys_node_dup_recursion(struct lys_module *module, struct lys_node *parent, const + return retval; + + error: +- lys_node_free(retval, NULL, 0); ++ lys_node_free(ctx, retval, NULL, 0); + return NULL; + } + +@@ -5149,7 +5144,7 @@ lys_submodule_module_data_free(struct lys_submodule *submodule) + /* remove parsed data */ + LY_TREE_FOR_SAFE(submodule->belongsto->data, next, elem) { + if (elem->module == (struct lys_module *)submodule) { +- lys_node_free(elem, NULL, 0); ++ lys_node_free(submodule->ctx, elem, NULL, 0); + } + } + } +@@ -5546,7 +5541,7 @@ lys_extension_instances_free(struct ly_ctx *ctx, struct lys_ext_instance **e, un + case LY_STMT_USES: + pp = (void**)&((struct lys_ext_instance_complex *)e[i])->content[substmt[j].offset]; + LY_TREE_FOR_SAFE((struct lys_node *)(*pp), snext, siter) { +- lys_node_free(siter, NULL, 0); ++ lys_node_free(ctx, siter, NULL, 0); + } + *pp = NULL; + break; diff --git a/libyang.spec b/libyang.spec index 4ef36dbfb6b5348419f1b1de4cefc3bbfcfad666..07da91cd6a14edbdffccf1817d36198feb7b6c25 100644 --- a/libyang.spec +++ b/libyang.spec @@ -1,7 +1,7 @@ %global debug_package %{nil} Name: libyang Version: 1.0.184 -Release: 1 +Release: 2 Summary: YANG data modeling language library Url: https://github.com/CESNET/libyang Source: %{url}/archive/%{name}-%{version}.tar.gz @@ -9,6 +9,7 @@ License: BSD Patch0: libyang-1.0.184-doc.patch Patch1: CVE-2021-28903.patch +Patch2: CVE-2021-28905.patch Requires: pcre BuildRequires: cmake @@ -127,6 +128,9 @@ cp -r doc/html %{buildroot}/%{_docdir}/libyang/html %{python3_sitearch}/__pycache__/yang* %changelog +* Mon Jun 28 2021 zhuqingfu - 1.0.184-2 +- Add patch CVE-2021-28905 + * Wed Jun 23 2021 yaozc7 - 1.0.184-1 - Add patch CVE-2021-28903