In the functions create_initial_state() and calc_eclosure_iter(), memory is
allocated for the elems member of a re_node_set structure but that memory
isn't freed on error. Adding a call to re_node_set_free() before returning an
error will solve this issue.

This issue was found by a Coverity Scan of GRUB2 under the following CIDs:
CID: 473869
CID: 473888

Signed-off-by: Alec Brown <alec.r.br...@oracle.com>
---
 lib/regcomp.c | 20 ++++++++++++++++----
 1 file changed, 16 insertions(+), 4 deletions(-)

diff --git a/lib/regcomp.c b/lib/regcomp.c
index a23f289d7a..170c26cf05 100644
--- a/lib/regcomp.c
+++ b/lib/regcomp.c
@@ -1014,7 +1014,10 @@ create_initial_state (re_dfa_t *dfa)
   dfa->init_state = re_acquire_state_context (&err, dfa, &init_nodes, 0);
   /* We don't check ERR here, since the initial state must not be NULL.  */
   if (__glibc_unlikely (dfa->init_state == NULL))
-    return err;
+    {
+      re_node_set_free (&init_nodes);
+      return err;
+    }
   if (dfa->init_state->has_constraint)
     {
       dfa->init_state_word = re_acquire_state_context (&err, dfa, &init_nodes,
@@ -1028,7 +1031,10 @@ create_initial_state (re_dfa_t *dfa)
       if (__glibc_unlikely (dfa->init_state_word == NULL
                            || dfa->init_state_nl == NULL
                            || dfa->init_state_begbuf == NULL))
-       return err;
+       {
+         re_node_set_free (&init_nodes);
+         return err;
+       }
     }
   else
     dfa->init_state_word = dfa->init_state_nl
@@ -1678,7 +1684,10 @@ calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa, 
Idx node, bool root)
       err = duplicate_node_closure (dfa, node, node, node,
                                    dfa->nodes[node].constraint);
       if (__glibc_unlikely (err != REG_NOERROR))
-       return err;
+       {
+         re_node_set_free (&eclosure);
+         return err;
+       }
     }
 
   /* Expand each epsilon destination nodes.  */
@@ -1700,7 +1709,10 @@ calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa, 
Idx node, bool root)
          {
            err = calc_eclosure_iter (&eclosure_elem, dfa, edest, false);
            if (__glibc_unlikely (err != REG_NOERROR))
-             return err;
+             {
+               re_node_set_free (&eclosure);
+               return err;
+             }
          }
        else
          eclosure_elem = dfa->eclosures[edest];
-- 
2.43.5


Reply via email to