summaryrefslogtreecommitdiff
path: root/debian/patches/Fix-bad-compile-for-groups-like-2-0-1999.patch
diff options
context:
space:
mode:
Diffstat (limited to 'debian/patches/Fix-bad-compile-for-groups-like-2-0-1999.patch')
-rw-r--r--debian/patches/Fix-bad-compile-for-groups-like-2-0-1999.patch209
1 files changed, 209 insertions, 0 deletions
diff --git a/debian/patches/Fix-bad-compile-for-groups-like-2-0-1999.patch b/debian/patches/Fix-bad-compile-for-groups-like-2-0-1999.patch
new file mode 100644
index 0000000..f019be6
--- /dev/null
+++ b/debian/patches/Fix-bad-compile-for-groups-like-2-0-1999.patch
@@ -0,0 +1,209 @@
+Description: CVE-2015-2325: heap buffer overflow in compile_branch()
+ Fix bad compile for groups like "((?2){0,1999}())?".
+Origin: backport, http://vcs.pcre.org/pcre?view=revision&revision=1528
+Bug: http://bugs.exim.org/show_bug.cgi?id=1591
+Bug-Debian: https://bugs.debian.org/781795
+Forwarded: not-needed
+Last-Update: 2015-09-10
+Applied-Upstream: 8.37
+
+--- a/pcre_compile.c
++++ b/pcre_compile.c
+@@ -3933,14 +3933,14 @@ Arguments:
+ adjust the amount by which the group is to be moved
+ utf TRUE in UTF-8 / UTF-16 / UTF-32 mode
+ cd contains pointers to tables etc.
+- save_hwm the hwm forward reference pointer at the start of the group
++ save_hwm_offset the hwm forward reference offset at the start of the group
+
+ Returns: nothing
+ */
+
+ static void
+ adjust_recurse(pcre_uchar *group, int adjust, BOOL utf, compile_data *cd,
+- pcre_uchar *save_hwm)
++ size_t save_hwm_offset)
+ {
+ pcre_uchar *ptr = group;
+
+@@ -3952,7 +3952,8 @@ while ((ptr = (pcre_uchar *)find_recurse
+ /* See if this recursion is on the forward reference list. If so, adjust the
+ reference. */
+
+- for (hc = save_hwm; hc < cd->hwm; hc += LINK_SIZE)
++ for (hc = (pcre_uchar *)cd->start_workspace + save_hwm_offset; hc < cd->hwm;
++ hc += LINK_SIZE)
+ {
+ offset = (int)GET(hc, 0);
+ if (cd->start_code + offset == ptr + 1)
+@@ -4397,7 +4398,7 @@ const pcre_uchar *tempptr;
+ const pcre_uchar *nestptr = NULL;
+ pcre_uchar *previous = NULL;
+ pcre_uchar *previous_callout = NULL;
+-pcre_uchar *save_hwm = NULL;
++size_t save_hwm_offset = 0;
+ pcre_uint8 classbits[32];
+
+ /* We can fish out the UTF-8 setting once and for all into a BOOL, but we
+@@ -5909,7 +5910,7 @@ for (;; ptr++)
+ if (repeat_max <= 1) /* Covers 0, 1, and unlimited */
+ {
+ *code = OP_END;
+- adjust_recurse(previous, 1, utf, cd, save_hwm);
++ adjust_recurse(previous, 1, utf, cd, save_hwm_offset);
+ memmove(previous + 1, previous, IN_UCHARS(len));
+ code++;
+ if (repeat_max == 0)
+@@ -5933,7 +5934,7 @@ for (;; ptr++)
+ {
+ int offset;
+ *code = OP_END;
+- adjust_recurse(previous, 2 + LINK_SIZE, utf, cd, save_hwm);
++ adjust_recurse(previous, 2 + LINK_SIZE, utf, cd, save_hwm_offset);
+ memmove(previous + 2 + LINK_SIZE, previous, IN_UCHARS(len));
+ code += 2 + LINK_SIZE;
+ *previous++ = OP_BRAZERO + repeat_type;
+@@ -5996,26 +5997,25 @@ for (;; ptr++)
+ for (i = 1; i < repeat_min; i++)
+ {
+ pcre_uchar *hc;
+- pcre_uchar *this_hwm = cd->hwm;
++ size_t this_hwm_offset = cd->hwm - cd->start_workspace;
+ memcpy(code, previous, IN_UCHARS(len));
+
+ while (cd->hwm > cd->start_workspace + cd->workspace_size -
+- WORK_SIZE_SAFETY_MARGIN - (this_hwm - save_hwm))
++ WORK_SIZE_SAFETY_MARGIN -
++ (this_hwm_offset - save_hwm_offset))
+ {
+- int save_offset = save_hwm - cd->start_workspace;
+- int this_offset = this_hwm - cd->start_workspace;
+ *errorcodeptr = expand_workspace(cd);
+ if (*errorcodeptr != 0) goto FAILED;
+- save_hwm = (pcre_uchar *)cd->start_workspace + save_offset;
+- this_hwm = (pcre_uchar *)cd->start_workspace + this_offset;
+ }
+
+- for (hc = save_hwm; hc < this_hwm; hc += LINK_SIZE)
++ for (hc = (pcre_uchar *)cd->start_workspace + save_hwm_offset;
++ hc < (pcre_uchar *)cd->start_workspace + this_hwm_offset;
++ hc += LINK_SIZE)
+ {
+ PUT(cd->hwm, 0, GET(hc, 0) + len);
+ cd->hwm += LINK_SIZE;
+ }
+- save_hwm = this_hwm;
++ save_hwm_offset = this_hwm_offset;
+ code += len;
+ }
+ }
+@@ -6060,7 +6060,7 @@ for (;; ptr++)
+ else for (i = repeat_max - 1; i >= 0; i--)
+ {
+ pcre_uchar *hc;
+- pcre_uchar *this_hwm = cd->hwm;
++ size_t this_hwm_offset = cd->hwm - cd->start_workspace;
+
+ *code++ = OP_BRAZERO + repeat_type;
+
+@@ -6082,22 +6082,21 @@ for (;; ptr++)
+ copying them. */
+
+ while (cd->hwm > cd->start_workspace + cd->workspace_size -
+- WORK_SIZE_SAFETY_MARGIN - (this_hwm - save_hwm))
++ WORK_SIZE_SAFETY_MARGIN -
++ (this_hwm_offset - save_hwm_offset))
+ {
+- int save_offset = save_hwm - cd->start_workspace;
+- int this_offset = this_hwm - cd->start_workspace;
+ *errorcodeptr = expand_workspace(cd);
+ if (*errorcodeptr != 0) goto FAILED;
+- save_hwm = (pcre_uchar *)cd->start_workspace + save_offset;
+- this_hwm = (pcre_uchar *)cd->start_workspace + this_offset;
+ }
+
+- for (hc = save_hwm; hc < this_hwm; hc += LINK_SIZE)
++ for (hc = (pcre_uchar *)cd->start_workspace + save_hwm_offset;
++ hc < (pcre_uchar *)cd->start_workspace + this_hwm_offset;
++ hc += LINK_SIZE)
+ {
+ PUT(cd->hwm, 0, GET(hc, 0) + len + ((i != 0)? 2+LINK_SIZE : 1));
+ cd->hwm += LINK_SIZE;
+ }
+- save_hwm = this_hwm;
++ save_hwm_offset = this_hwm_offset;
+ code += len;
+ }
+
+@@ -6193,7 +6192,7 @@ for (;; ptr++)
+ {
+ int nlen = (int)(code - bracode);
+ *code = OP_END;
+- adjust_recurse(bracode, 1 + LINK_SIZE, utf, cd, save_hwm);
++ adjust_recurse(bracode, 1 + LINK_SIZE, utf, cd, save_hwm_offset);
+ memmove(bracode + 1 + LINK_SIZE, bracode, IN_UCHARS(nlen));
+ code += 1 + LINK_SIZE;
+ nlen += 1 + LINK_SIZE;
+@@ -6327,7 +6326,7 @@ for (;; ptr++)
+ else
+ {
+ *code = OP_END;
+- adjust_recurse(tempcode, 1 + LINK_SIZE, utf, cd, save_hwm);
++ adjust_recurse(tempcode, 1 + LINK_SIZE, utf, cd, save_hwm_offset);
+ memmove(tempcode + 1 + LINK_SIZE, tempcode, IN_UCHARS(len));
+ code += 1 + LINK_SIZE;
+ len += 1 + LINK_SIZE;
+@@ -6376,7 +6375,7 @@ for (;; ptr++)
+
+ default:
+ *code = OP_END;
+- adjust_recurse(tempcode, 1 + LINK_SIZE, utf, cd, save_hwm);
++ adjust_recurse(tempcode, 1 + LINK_SIZE, utf, cd, save_hwm_offset);
+ memmove(tempcode + 1 + LINK_SIZE, tempcode, IN_UCHARS(len));
+ code += 1 + LINK_SIZE;
+ len += 1 + LINK_SIZE;
+@@ -6408,7 +6407,7 @@ for (;; ptr++)
+ newoptions = options;
+ skipbytes = 0;
+ bravalue = OP_CBRA;
+- save_hwm = cd->hwm;
++ save_hwm_offset = cd->hwm - cd->start_workspace;
+ reset_bracount = FALSE;
+
+ /* First deal with various "verbs" that can be introduced by '*'. */
+@@ -7701,7 +7700,7 @@ for (;; ptr++)
+ const pcre_uchar *p;
+ pcre_uint32 cf;
+
+- save_hwm = cd->hwm; /* Normally this is set when '(' is read */
++ save_hwm_offset = cd->hwm - cd->start_workspace; /* Normally this is set when '(' is read */
+ terminator = (*(++ptr) == CHAR_LESS_THAN_SIGN)?
+ CHAR_GREATER_THAN_SIGN : CHAR_APOSTROPHE;
+
+@@ -8247,7 +8246,7 @@ for (;;)
+ {
+ *code = OP_END;
+ adjust_recurse(start_bracket, 1 + LINK_SIZE,
+- (options & PCRE_UTF8) != 0, cd, cd->hwm);
++ (options & PCRE_UTF8) != 0, cd, cd->hwm - cd->start_workspace);
+ memmove(start_bracket + 1 + LINK_SIZE, start_bracket,
+ IN_UCHARS(code - start_bracket));
+ *start_bracket = OP_ONCE;
+--- a/testdata/testinput2
++++ b/testdata/testinput2
+@@ -4064,4 +4064,6 @@ backtracking verbs. --/
+
+ /(((((a)))))/Q
+
++"((?2){0,1999}())?"
++
+ /-- End of testinput2 --/
+--- a/testdata/testoutput2
++++ b/testdata/testoutput2
+@@ -14173,4 +14173,6 @@ Failed: parentheses are too deeply neste
+ /(((((a)))))/Q
+ ** Missing 0 or 1 after /Q
+
++"((?2){0,1999}())?"
++
+ /-- End of testinput2 --/