From: Peter Marko <[email protected]> Pick patch per [1] since [2] does not provide valid commit hash.
[1] https://security-tracker.debian.org/tracker/CVE-2026-86145 [2] https://github.com/PCRE2Project/pcre2/security/advisories/GHSA-3r4p-g7gg-ppmf Signed-off-by: Peter Marko <[email protected]> --- .../libpcre/libpcre2/CVE-2026-86145.patch | 158 ++++++++++++++++++ .../recipes-support/libpcre/libpcre2_10.47.bb | 1 + 2 files changed, 159 insertions(+) create mode 100644 meta/recipes-support/libpcre/libpcre2/CVE-2026-86145.patch diff --git a/meta/recipes-support/libpcre/libpcre2/CVE-2026-86145.patch b/meta/recipes-support/libpcre/libpcre2/CVE-2026-86145.patch new file mode 100644 index 0000000000..a044a006e5 --- /dev/null +++ b/meta/recipes-support/libpcre/libpcre2/CVE-2026-86145.patch @@ -0,0 +1,158 @@ +From c932e70451eafef922ebef364ac25042f0031135 Mon Sep 17 00:00:00 2001 +From: Nicholas Wilson <[email protected]> +Date: Thu, 27 Aug 2026 16:52:16 +0100 +Subject: [PATCH] Fix DFA workspace overflows; see GHSA-3r4p-g7gg-ppmf for + details + +CVE: CVE-2026-86145 +Upstream-Status: Backport [https://github.com/PCRE2Project/pcre2/commit/c932e70451eafef922ebef364ac25042f0031135] +Signed-off-by: Peter Marko <[email protected]> +--- + src/pcre2_dfa_match.c | 44 ++++++++++++++++++++++++++++++++++++------- + testdata/testinput6 | 7 +++++++ + testdata/testoutput6 | 8 ++++++++ + 3 files changed, 52 insertions(+), 7 deletions(-) + +diff --git a/src/pcre2_dfa_match.c b/src/pcre2_dfa_match.c +index 314e9775..8e9512c4 100644 +--- a/src/pcre2_dfa_match.c ++++ b/src/pcre2_dfa_match.c +@@ -405,8 +405,8 @@ return (mb->callout)(cb, mb->callout_data); + + /* This function is called when internal_dfa_match() is about to be called + recursively and there is insufficient working space left in the current +-workspace block. If there's an existing next block, use it; otherwise get a new +-block unless the heap limit is reached. ++workspace block. If there's a sufficiently large next block, use it; get a new ++block unless the heap limit is (or has been) reached. + + Arguments: + rwsptr pointer to block pointer (updated) +@@ -422,9 +422,18 @@ more_workspace(RWS_anchor **rwsptr, unsigned int ovecsize, dfa_match_block *mb) + { + RWS_anchor *rws = *rwsptr; + RWS_anchor *new; ++uint32_t requested; ++ ++PCRE2_ASSERT(ovecsize <= UINT32_MAX - RWS_RSIZE - RWS_ANCHOR_SIZE); ++requested = RWS_RSIZE + ovecsize + RWS_ANCHOR_SIZE; + + if (rws->next != NULL) + { ++ /* Although the initial block is large, and subsequent ones try to double, the ++ heap limit may cause the last one to be smaller; in this case, we have already ++ hit the heap limit and allocating a larger block will not be possible. */ ++ if (rws->next->size < requested) ++ return PCRE2_ERROR_HEAPLIMIT; + new = rws->next; + } + +@@ -434,14 +443,30 @@ overflow. */ + + else + { +- uint32_t newsize = (rws->size >= UINT32_MAX/(sizeof(int)*2))? UINT32_MAX/sizeof(int) : rws->size * 2; ++ uint32_t newsize = (rws->size >= (UINT32_MAX/sizeof(int))/2)? ++ UINT32_MAX/sizeof(int) : rws->size * 2; + uint32_t newsizeK = newsize/(1024/sizeof(int)); + +- if (newsizeK + mb->heap_used > mb->heap_limit) +- newsizeK = (uint32_t)(mb->heap_limit - mb->heap_used); +- newsize = newsizeK*(1024/sizeof(int)); ++ /* Clamp the allocation to the remaining heap allowance with care for overflows */ + +- if (newsize < RWS_RSIZE + ovecsize + RWS_ANCHOR_SIZE) ++ if (mb->heap_used >= mb->heap_limit) ++ { ++ newsize = 0; ++ newsizeK = 0; ++ } ++ else ++ { ++ PCRE2_SIZE availableK = mb->heap_limit - mb->heap_used; ++ /* newsize always capped at UINT32_MAX/sizeof(int), so newsizeK also capped; ++ and - if availableK is smaller - then multiplication to form newsize is safe */ ++ if (newsizeK > availableK) ++ { ++ newsize = (uint32_t)(availableK*(1024/sizeof(int))); ++ newsizeK = availableK; ++ } ++ } ++ ++ if (newsize < requested) + return PCRE2_ERROR_HEAPLIMIT; + new = mb->memctl.malloc(newsize*sizeof(int), mb->memctl.memory_data); + if (new == NULL) return PCRE2_ERROR_NOMEMORY; +@@ -2801,6 +2826,7 @@ for (;;) + + local_offsets = (PCRE2_SIZE *)(RWS + rws->size - rws->free); + local_workspace = ((int *)local_offsets) + RWS_OVEC_OSIZE; ++ PCRE2_ASSERT(rws->free >= RWS_RSIZE + RWS_OVEC_OSIZE); + rws->free -= RWS_RSIZE + RWS_OVEC_OSIZE; + + while (*endasscode == OP_ALT) endasscode += GET(endasscode, 1); +@@ -2900,6 +2926,7 @@ for (;;) + + local_offsets = (PCRE2_SIZE *)(RWS + rws->size - rws->free); + local_workspace = ((int *)local_offsets) + RWS_OVEC_OSIZE; ++ PCRE2_ASSERT(rws->free >= RWS_RSIZE + RWS_OVEC_OSIZE); + rws->free -= RWS_RSIZE + RWS_OVEC_OSIZE; + + while (*endasscode == OP_ALT) endasscode += GET(endasscode, 1); +@@ -2951,6 +2978,7 @@ for (;;) + + local_offsets = (PCRE2_SIZE *)(RWS + rws->size - rws->free); + local_workspace = ((int *)local_offsets) + RWS_OVEC_RSIZE; ++ PCRE2_ASSERT(rws->free >= RWS_RSIZE + RWS_OVEC_RSIZE); + rws->free -= RWS_RSIZE + RWS_OVEC_RSIZE; + + /* Check for repeating a recursion without advancing the subject +@@ -3050,6 +3078,7 @@ for (;;) + + local_offsets = (PCRE2_SIZE *)(RWS + rws->size - rws->free); + local_workspace = ((int *)local_offsets) + RWS_OVEC_OSIZE; ++ PCRE2_ASSERT(rws->free >= RWS_RSIZE + RWS_OVEC_OSIZE); + rws->free -= RWS_RSIZE + RWS_OVEC_OSIZE; + + if (codevalue == OP_BRAPOSZERO) +@@ -3149,6 +3178,7 @@ for (;;) + + local_offsets = (PCRE2_SIZE *)(RWS + rws->size - rws->free); + local_workspace = ((int *)local_offsets) + RWS_OVEC_OSIZE; ++ PCRE2_ASSERT(rws->free >= RWS_RSIZE + RWS_OVEC_OSIZE); + rws->free -= RWS_RSIZE + RWS_OVEC_OSIZE; + + rc = internal_dfa_match( +diff --git a/testdata/testinput6 b/testdata/testinput6 +index f6f5cbf4..197f6f76 100644 +--- a/testdata/testinput6 ++++ b/testdata/testinput6 +@@ -5263,4 +5263,11 @@ + abc\=replace=xyz + abc\=replace=xyz,substitute_matched + ++# -------------- ++ ++# Test workspace resizing and workspace re-use ++ ++/(*LIMIT_HEAP=4)(?=(?=(?=(?=(?=(?=(?=(?=a))(?R)))))))./ ++ a\=dfa ++ + # End of testinput6 +diff --git a/testdata/testoutput6 b/testdata/testoutput6 +index 8ecf0040..4316c8a6 100644 +--- a/testdata/testoutput6 ++++ b/testdata/testoutput6 +@@ -8237,4 +8237,12 @@ Failed: error -42: pattern contains an item that is not supported for DFA matchi + abc\=replace=xyz,substitute_matched + Failed: error -41: function is not supported for DFA matching + ++# -------------- ++ ++# Test workspace resizing and workspace re-use ++ ++/(*LIMIT_HEAP=4)(?=(?=(?=(?=(?=(?=(?=(?=a))(?R)))))))./ ++ a\=dfa ++Failed: error -63: heap limit exceeded ++ + # End of testinput6 diff --git a/meta/recipes-support/libpcre/libpcre2_10.47.bb b/meta/recipes-support/libpcre/libpcre2_10.47.bb index 2f40ef463e..60ba56014b 100644 --- a/meta/recipes-support/libpcre/libpcre2_10.47.bb +++ b/meta/recipes-support/libpcre/libpcre2_10.47.bb @@ -20,6 +20,7 @@ SRC_URI = "${GITHUB_BASE_URI}/download/pcre2-${PV}/pcre2-${PV}.tar.bz2 \ file://CVE-2026-89157.patch \ file://CVE-2026-89160.patch \ file://CVE-2026-89158.patch \ + file://CVE-2026-86145.patch \ " GITHUB_BASE_URI = "https://github.com/PCRE2Project/pcre2/releases"
-=-=-=-=-=-=-=-=-=-=-=- Links: You receive all messages sent to this group. View/Reply Online (#247482): https://lists.openembedded.org/g/openembedded-core/message/247482 Mute This Topic: https://lists.openembedded.org/mt/121676856/21656 Group Owner: [email protected] Unsubscribe: https://lists.openembedded.org/g/openembedded-core/unsub [[email protected]] -=-=-=-=-=-=-=-=-=-=-=-
