diff --git a/bootstrap.conf b/bootstrap.conf index 7a7813d28..7a464a289 100644 --- a/bootstrap.conf +++ b/bootstrap.conf @@ -84,7 +84,10 @@ bootstrap_post_import_hook () { # Instead of patching our gnulib and therefore maintaining a fork, submit # changes to gnulib and update the hash above when they've merged. Do not # add new patches here. - patch -d grub-core/lib/gnulib -p2 < grub-core/lib/gnulib-patches/fix-width.patch + for patchname in fix-width fix-regcomp-resource-leak; do + patch -d grub-core/lib/gnulib -p2 \ + < "grub-core/lib/gnulib-patches/$patchname.patch" + done for patchname in \ 0001-Support-POTFILES-shell \ diff --git a/conf/Makefile.extra-dist b/conf/Makefile.extra-dist index b61052a18..230a1d68f 100644 --- a/conf/Makefile.extra-dist +++ b/conf/Makefile.extra-dist @@ -29,6 +29,7 @@ EXTRA_DIST += grub-core/genemuinit.sh EXTRA_DIST += grub-core/genemuinitheader.sh EXTRA_DIST += grub-core/lib/gnulib-patches/fix-width.patch +EXTRA_DIST += grub-core/lib/gnulib-patches/fix-regcomp-resource-leak.patch EXTRA_DIST += grub-core/lib/libgcrypt EXTRA_DIST += grub-core/lib/libgcrypt-grub/mpi/generic diff --git a/grub-core/lib/gnulib-patches/fix-regcomp-resource-leak.patch b/grub-core/lib/gnulib-patches/fix-regcomp-resource-leak.patch new file mode 100644 index 000000000..b2e900023 --- /dev/null +++ b/grub-core/lib/gnulib-patches/fix-regcomp-resource-leak.patch @@ -0,0 +1,110 @@ +--- a/lib/regcomp.c ++++ b/lib/regcomp.c +@@ -1001,21 +1001,25 @@ create_initial_state (re_dfa_t *dfa) + Idx dest_idx = dfa->edests[node_idx].elems[0]; + if (!re_node_set_contains (&init_nodes, dest_idx)) + { +- reg_errcode_t merge_err ++ err + = re_node_set_merge (&init_nodes, dfa->eclosures + dest_idx); +- if (merge_err != REG_NOERROR) +- return merge_err; ++ if (err != REG_NOERROR) ++ break; + i = 0; + } + } + } + + /* It must be the first time to invoke acquire_state. */ +- 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. */ ++ dfa->init_state ++ = (err == REG_NOERROR ++ ? re_acquire_state_context (&err, dfa, &init_nodes, 0) ++ : NULL); + if (__glibc_unlikely (dfa->init_state == NULL)) +- return err; +- if (dfa->init_state->has_constraint) ++ { ++ /* Don't check ERR here, as the initial state must not be null. */ ++ } ++ else if (dfa->init_state->has_constraint) + { + dfa->init_state_word = re_acquire_state_context (&err, dfa, &init_nodes, + CONTEXT_WORD); +@@ -1025,17 +1029,13 @@ create_initial_state (re_dfa_t *dfa) + &init_nodes, + CONTEXT_NEWLINE + | CONTEXT_BEGBUF); +- if (__glibc_unlikely (dfa->init_state_word == NULL +- || dfa->init_state_nl == NULL +- || dfa->init_state_begbuf == NULL)) +- return err; + } + else + dfa->init_state_word = dfa->init_state_nl + = dfa->init_state_begbuf = dfa->init_state; + + re_node_set_free (&init_nodes); +- return REG_NOERROR; ++ return err; + } + + /* If it is possible to do searching in single byte encoding instead of UTF-8 +@@ -1677,12 +1677,11 @@ 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; + } + + /* Expand each epsilon destination nodes. */ +- if (IS_EPSILON_NODE(dfa->nodes[node].type)) ++ if (__glibc_likely (err == REG_NOERROR) ++ && IS_EPSILON_NODE (dfa->nodes[node].type)) + for (i = 0; i < dfa->edests[node].nelem; ++i) + { + re_node_set eclosure_elem; +@@ -1700,14 +1699,14 @@ 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; ++ break; + } + else + eclosure_elem = dfa->eclosures[edest]; + /* Merge the epsilon closure of 'edest'. */ + err = re_node_set_merge (&eclosure, &eclosure_elem); + if (__glibc_unlikely (err != REG_NOERROR)) +- return err; ++ break; + /* If the epsilon closure of 'edest' is incomplete, + the epsilon closure of this node is also incomplete. */ + if (dfa->eclosures[edest].nelem == 0) +@@ -1717,12 +1716,18 @@ calc_eclosure_iter (re_node_set *new_set, re_dfa_t *dfa, Idx node, bool root) + } + } + +- if (incomplete && !root) +- dfa->eclosures[node].nelem = 0; ++ if (err != REG_NOERROR) ++ re_node_set_free (&eclosure); + else +- dfa->eclosures[node] = eclosure; +- *new_set = eclosure; +- return REG_NOERROR; ++ { ++ if (incomplete && !root) ++ dfa->eclosures[node].nelem = 0; ++ else ++ dfa->eclosures[node] = eclosure; ++ *new_set = eclosure; ++ } ++ ++ return err; + } + + /* Functions for token which are used in the parser. */