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