Blame SOURCES/pcre2-10.32-Fix-heap-limit-checking-overflow-bug-in-pcre2_dfa_ma.patch

9a6b56
From 18ee5a9d3779f5e8ee3142326dd65ae75b22bb0b Mon Sep 17 00:00:00 2001
9a6b56
From: ph10 <ph10@6239d852-aaf2-0410-a92c-79f79f948069>
9a6b56
Date: Mon, 22 Oct 2018 16:47:55 +0000
9a6b56
Subject: [PATCH] Fix heap limit checking overflow bug in pcre2_dfa_match().
9a6b56
MIME-Version: 1.0
9a6b56
Content-Type: text/plain; charset=UTF-8
9a6b56
Content-Transfer-Encoding: 8bit
9a6b56
9a6b56
git-svn-id: svn://vcs.exim.org/pcre2/code/trunk@1034 6239d852-aaf2-0410-a92c-79f79f948069
9a6b56
9a6b56
Petr Písař: Ported to 10.32.
9a6b56
9a6b56
Signed-off-by: Petr Písař <ppisar@redhat.com>
9a6b56
---
9a6b56
 src/pcre2_dfa_match.c | 22 +++++++++++++---------
9a6b56
 1 file changed, 13 insertions(+), 9 deletions(-)
9a6b56
9a6b56
diff --git a/src/pcre2_dfa_match.c b/src/pcre2_dfa_match.c
9a6b56
index 9b43237..818004d 100644
9a6b56
--- a/src/pcre2_dfa_match.c
9a6b56
+++ b/src/pcre2_dfa_match.c
9a6b56
@@ -316,8 +316,8 @@ finding the minimum heap requirement for a match. */
9a6b56
 
9a6b56
 typedef struct RWS_anchor {
9a6b56
   struct RWS_anchor *next;
9a6b56
-  unsigned int size;  /* Number of ints */
9a6b56
-  unsigned int free;  /* Number of ints */
9a6b56
+  uint32_t size;  /* Number of ints */
9a6b56
+  uint32_t free;  /* Number of ints */
9a6b56
 } RWS_anchor;
9a6b56
 
9a6b56
 #define RWS_ANCHOR_SIZE (sizeof(RWS_anchor)/sizeof(int))
9a6b56
@@ -413,20 +413,24 @@ if (rws->next != NULL)
9a6b56
   new = rws->next;
9a6b56
   }
9a6b56
 
9a6b56
-/* All sizes are in units of sizeof(int), except for mb->heaplimit, which is in
9a6b56
-kibibytes. */
9a6b56
+/* Sizes in the RWS_anchor blocks are in units of sizeof(int), but
9a6b56
+mb->heap_limit and mb->heap_used are in kibibytes. Play carefully, to avoid
9a6b56
+overflow. */
9a6b56
 
9a6b56
 else
9a6b56
   {
9a6b56
-  unsigned int newsize = rws->size * 2;
9a6b56
-  unsigned int heapleft = (unsigned int)
9a6b56
-    (((1024/sizeof(int))*mb->heap_limit - mb->heap_used));
9a6b56
-  if (newsize > heapleft) newsize = heapleft;
9a6b56
+  uint32_t newsize = (rws->size >= UINT32_MAX/2)? UINT32_MAX/2 : rws->size * 2;
9a6b56
+  uint32_t newsizeK = newsize/(1024/sizeof(int));
9a6b56
+
9a6b56
+  if (newsizeK + mb->heap_used > mb->heap_limit)
9a6b56
+    newsizeK = mb->heap_limit - mb->heap_used;
9a6b56
+  newsize = newsizeK*(1024/sizeof(int));
9a6b56
+
9a6b56
   if (newsize < RWS_RSIZE + ovecsize + RWS_ANCHOR_SIZE)
9a6b56
     return PCRE2_ERROR_HEAPLIMIT;
9a6b56
   new = mb->memctl.malloc(newsize*sizeof(int), mb->memctl.memory_data);
9a6b56
   if (new == NULL) return PCRE2_ERROR_NOMEMORY;
9a6b56
-  mb->heap_used += newsize;
9a6b56
+  mb->heap_used += newsizeK;
9a6b56
   new->next = NULL;
9a6b56
   new->size = newsize;
9a6b56
   rws->next = new;
9a6b56
-- 
9a6b56
2.17.2
9a6b56