CVE-2019-3817: Use After Free (CWE-416)
value: A use-after-free flaw has been discovered in libcomps before version 0.1.10 in the way ObjMRTrees are merged. An attacker, who is able to make an application read a crafted comps XML file, may be able to crash the application or execute malicious code.
CWE description: The product reuses or references memory after it has been freed. At some point afterward, the memory may be allocated again and saved in another pointer, while the original pointer references a location somewhere within the new allocation. Any operations using the original pointer are no longer valid because the memory "belongs" to the code that operates on the new pointer.
CVSS v3 base score: 8.8
Published: 2019-03-27T13:29Z
Repository: https://github.com/rpm-software-management/libcomps
Language: C
Files changed: libcomps/src/comps_mradix.c, libcomps/src/comps_objmradix.c, libcomps/src/comps_objradix.c, libcomps/src/comps_radix.c
Commit date: 2019-01-22 11:23:38 +0100
Commit message: Fix UAF in comps_objmrtree_unite function

The added field is not used at all in many places and it is probably the
left-over of some copy-paste.

Diff: diff --git a/libcomps/src/comps_mradix.c b/libcomps/src/comps_mradix.c
index 8ef9640..dfdee8e 100644
--- a/libcomps/src/comps_mradix.c
+++ b/libcomps/src/comps_mradix.c
@@ -175,11 +175,10 @@ void comps_mrtree_unite(COMPS_MRTree *rt1, COMPS_MRTree *rt2) {
     COMPS_HSList *tmplist, *tmp_subnodes;
     COMPS_HSListItem *it, *it2;
     struct Pair {
         COMPS_HSList * subnodes;
         char * key;
-        char added;
     } *pair, *parent_pair;
 
     pair = malloc(sizeof(struct Pair));
     pair->subnodes = rt2->subnodes;
     pair->key = NULL;
@@ -193,11 +192,10 @@ void comps_mrtree_unite(COMPS_MRTree *rt1, COMPS_MRTree *rt2) {
         comps_hslist_remove(tmplist, tmplist->first);
         tmp_subnodes = ((struct Pair*)it->data)->subnodes;
         parent_pair = (struct Pair*) it->data;
         free(it);
 
-        pair->added = 0;
         for (it = tmp_subnodes->first; it != NULL; it=it->next) {
             pair = malloc(sizeof(struct Pair));
             pair->subnodes = ((COMPS_MRTreeData*)it->data)->subnodes;
 
             if (parent_pair->key != NULL) {
diff --git a/libcomps/src/comps_objmradix.c b/libcomps/src/comps_objmradix.c
index 9a2038b..22ad262 100644
--- a/libcomps/src/comps_objmradix.c
+++ b/libcomps/src/comps_objmradix.c
@@ -283,11 +283,10 @@ void comps_objmrtree_unite(COMPS_ObjMRTree *rt1, COMPS_ObjMRTree *rt2) {
     COMPS_HSListItem *it;
     COMPS_ObjListIt *it2;
     struct Pair {
         COMPS_HSList * subnodes;
         char * key;
-        char added;
     } *pair, *parent_pair;
 
     pair = malloc(sizeof(struct Pair));
     pair->subnodes = rt2->subnodes;
     pair->key = NULL;
@@ -301,11 +300,10 @@ void comps_objmrtree_unite(COMPS_ObjMRTree *rt1, COMPS_ObjMRTree *rt2) {
         comps_hslist_remove(tmplist, tmplist->first);
         tmp_subnodes = ((struct Pair*)it->data)->subnodes;
         parent_pair = (struct Pair*) it->data;
         free(it);
 
-        pair->added = 0;
         for (it = tmp_subnodes->first; it != NULL; it=it->next) {
             pair = malloc(sizeof(struct Pair));
             pair->subnodes = ((COMPS_ObjMRTreeData*)it->data)->subnodes;
 
             if (parent_pair->key != NULL) {
diff --git a/libcomps/src/comps_objradix.c b/libcomps/src/comps_objradix.c
index c657b75..840592a 100644
--- a/libcomps/src/comps_objradix.c
+++ b/libcomps/src/comps_objradix.c
@@ -695,11 +695,10 @@ void comps_objrtree_unite(COMPS_ObjRTree *rt1, COMPS_ObjRTree *rt2) {
     COMPS_HSList *tmplist, *tmp_subnodes;
     COMPS_HSListItem *it;
     struct Pair {
         COMPS_HSList * subnodes;
         char * key;
-        char added;
     } *pair, *parent_pair;
 
     pair = malloc(sizeof(struct Pair));
     pair->subnodes = rt2->subnodes;
     pair->key = NULL;
@@ -714,11 +713,10 @@ void comps_objrtree_unite(COMPS_ObjRTree *rt1, COMPS_ObjRTree *rt2) {
         tmp_subnodes = ((struct Pair*)it->data)->subnodes;
         parent_pair = (struct Pair*) it->data;
         //printf("key-part:%s\n", parent_pair->key);
         free(it);
 
-        //pair->added = 0;
         for (it = tmp_subnodes->first; it != NULL; it=it->next) {
             pair = malloc(sizeof(struct Pair));
             pair->subnodes = ((COMPS_ObjRTreeData*)it->data)->subnodes;
 
             if (parent_pair->key != NULL) {
diff --git a/libcomps/src/comps_radix.c b/libcomps/src/comps_radix.c
index ada4fda..05dcaf2 100644
--- a/libcomps/src/comps_radix.c
+++ b/libcomps/src/comps_radix.c
@@ -527,11 +527,10 @@ void comps_rtree_unite(COMPS_RTree *rt1, COMPS_RTree *rt2) {
     COMPS_HSList *tmplist, *tmp_subnodes;
     COMPS_HSListItem *it;
     struct Pair {
         COMPS_HSList * subnodes;
         char * key;
-        char added;
     } *pair, *parent_pair;
 
     pair = malloc(sizeof(struct Pair));
     pair->subnodes = rt2->subnodes;
     pair->key = NULL;

Vulnerable code:         char added;
        pair->added = 0;
        char added;
        pair->added = 0;
        char added;
        //pair->added = 0;
        char added;