]> git.ipfire.org Git - ipfire-2.x.git/commitdiff
pcre: Fix more buffer overflows
authorMichael Tremer <michael.tremer@ipfire.org>
Fri, 21 Aug 2015 20:26:46 +0000 (21:26 +0100)
committerMichael Tremer <michael.tremer@ipfire.org>
Fri, 21 Aug 2015 20:29:46 +0000 (21:29 +0100)
This reverts commit cec620efdf2d0ab2c55b015ca7b8d6ca2a667e72.

Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
config/rootfiles/core/94/filelists/pcre [new symlink]
lfs/pcre
src/patches/pcre-8.37-Fix-another-buffer-overflow.patch [new file with mode: 0644]
src/patches/pcre-8.37-Fix-buffer-overflow-for-named-references-in-situatio.patch [new file with mode: 0644]
src/patches/pcre-8.37-Fix-named-forward-reference-to-duplicate-group-numbe.patch [new file with mode: 0644]

diff --git a/config/rootfiles/core/94/filelists/pcre b/config/rootfiles/core/94/filelists/pcre
new file mode 120000 (symlink)
index 0000000..b390d9a
--- /dev/null
@@ -0,0 +1 @@
+../../../common/pcre
\ No newline at end of file
index 8f207da7ba59f7259c857919319a9cb9f4d4054c..fd66350043986bf25a38d52680ddf10279914b85 100644 (file)
--- a/lfs/pcre
+++ b/lfs/pcre
@@ -72,6 +72,9 @@ $(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects))
        @rm -rf $(DIR_APP) && cd $(DIR_SRC) && tar axf $(DIR_DL)/$(DL_FILE)
        cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/pcre-8.37-Fix-buffer-overflow-for-named-recursive-back-referen.patch
        cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/pcre-8.37-Fix-buffer-overflow-for-forward-reference-within-bac.patch
+       cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/pcre-8.37-Fix-named-forward-reference-to-duplicate-group-numbe.patch
+       cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/pcre-8.37-Fix-another-buffer-overflow.patch
+       cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/pcre-8.37-Fix-buffer-overflow-for-named-references-in-situatio.patch
        cd $(DIR_APP) && ./configure \
                --prefix=/usr \
                --disable-static \
diff --git a/src/patches/pcre-8.37-Fix-another-buffer-overflow.patch b/src/patches/pcre-8.37-Fix-another-buffer-overflow.patch
new file mode 100644 (file)
index 0000000..20ead09
--- /dev/null
@@ -0,0 +1,110 @@
+From f6efcf125123199d446c5561266c3c3846ed9f30 Mon Sep 17 00:00:00 2001
+From: ph10 <ph10@2f5784b3-3f2a-0410-8824-cb99058d5e15>
+Date: Wed, 3 Jun 2015 16:51:59 +0000
+Subject: [PATCH] Fix another buffer overflow.
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Ported to 8.37:
+
+commit 225f0d5eb16c7a26591a1e3f286c7476907b5a6a
+Author: ph10 <ph10@2f5784b3-3f2a-0410-8824-cb99058d5e15>
+Date:   Wed Jun 3 16:51:59 2015 +0000
+
+    Fix another buffer overflow.
+
+    git-svn-id: svn://vcs.exim.org/pcre/code/trunk@1562 2f5784b3-3f2a-0410-8824-cb99058d5e15
+
+Signed-off-by: Petr Písař <ppisar@redhat.com>
+---
+ pcre_compile.c           | 7 ++++++-
+ testdata/testinput2      | 2 ++
+ testdata/testoutput11-16 | 2 +-
+ testdata/testoutput11-32 | 2 +-
+ testdata/testoutput11-8  | 2 +-
+ testdata/testoutput2     | 2 ++
+ 6 files changed, 13 insertions(+), 4 deletions(-)
+
+diff --git a/pcre_compile.c b/pcre_compile.c
+index 8b4aaef..f5d2384 100644
+--- a/pcre_compile.c
++++ b/pcre_compile.c
+@@ -7210,7 +7210,12 @@ for (;; ptr++)
+           real compile this will be picked up and the reference wrapped with
+           OP_ONCE to make it atomic, so we must space in case this occurs. */
+-          if (recno == 0) *lengthptr += 2 + 2*LINK_SIZE;
++          /* In fact, this can happen for a non-forward reference because
++          another group with the same number might be created later. This
++          issue is fixed "properly" in PCRE2. As PCRE1 is now in maintenance
++          only mode, we finesse the bug by allowing more memory always. */
++
++          /* if (recno == 0) */ *lengthptr += 2 + 2*LINK_SIZE;
+           }
+         /* In the real compile, search the name table. We check the name
+diff --git a/testdata/testinput2 b/testdata/testinput2
+index 5cc9ce6..e12de3a 100644
+--- a/testdata/testinput2
++++ b/testdata/testinput2
+@@ -4156,4 +4156,6 @@ backtracking verbs. --/
+ /(?=di(?<=(?1))|(?=(.))))/
++"(?J:(?|(?'R')(\k'R')|((?'R'))))"
++
+ /-- End of testinput2 --/
+diff --git a/testdata/testoutput11-16 b/testdata/testoutput11-16
+index 422f2ad..e222e7c 100644
+--- a/testdata/testoutput11-16
++++ b/testdata/testoutput11-16
+@@ -231,7 +231,7 @@ Memory allocation (code space): 73
+ ------------------------------------------------------------------
+ /(?P<a>a)...(?P=a)bbb(?P>a)d/BM
+-Memory allocation (code space): 61
++Memory allocation (code space): 77
+ ------------------------------------------------------------------
+   0  24 Bra
+   2   5 CBra 1
+diff --git a/testdata/testoutput11-32 b/testdata/testoutput11-32
+index d953ec8..9a80ec9 100644
+--- a/testdata/testoutput11-32
++++ b/testdata/testoutput11-32
+@@ -231,7 +231,7 @@ Memory allocation (code space): 155
+ ------------------------------------------------------------------
+ /(?P<a>a)...(?P=a)bbb(?P>a)d/BM
+-Memory allocation (code space): 125
++Memory allocation (code space): 157
+ ------------------------------------------------------------------
+   0  24 Bra
+   2   5 CBra 1
+diff --git a/testdata/testoutput11-8 b/testdata/testoutput11-8
+index 6ec18ec..3adaca2 100644
+--- a/testdata/testoutput11-8
++++ b/testdata/testoutput11-8
+@@ -231,7 +231,7 @@ Memory allocation (code space): 45
+ ------------------------------------------------------------------
+ /(?P<a>a)...(?P=a)bbb(?P>a)d/BM
+-Memory allocation (code space): 38
++Memory allocation (code space): 50
+ ------------------------------------------------------------------
+   0  30 Bra
+   3   7 CBra 1
+diff --git a/testdata/testoutput2 b/testdata/testoutput2
+index 4decb8d..5bad26c 100644
+--- a/testdata/testoutput2
++++ b/testdata/testoutput2
+@@ -14428,4 +14428,6 @@ Failed: lookbehind assertion is not fixed length at offset 17
+ /(?=di(?<=(?1))|(?=(.))))/
+ Failed: unmatched parentheses at offset 23
++"(?J:(?|(?'R')(\k'R')|((?'R'))))"
++
+ /-- End of testinput2 --/
+-- 
+2.4.3
+
diff --git a/src/patches/pcre-8.37-Fix-buffer-overflow-for-named-references-in-situatio.patch b/src/patches/pcre-8.37-Fix-buffer-overflow-for-named-references-in-situatio.patch
new file mode 100644 (file)
index 0000000..ab1b962
--- /dev/null
@@ -0,0 +1,190 @@
+From b3f0b0dd971314df8f865e221aa1a88e75d6d1a6 Mon Sep 17 00:00:00 2001
+From: ph10 <ph10@2f5784b3-3f2a-0410-8824-cb99058d5e15>
+Date: Wed, 5 Aug 2015 15:38:32 +0000
+Subject: [PATCH] Fix buffer overflow for named references in (?| situations.
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Ported for 8.37:
+
+commit 7af8e8717def179fd7b69e173abd347c1a3547cb
+Author: ph10 <ph10@2f5784b3-3f2a-0410-8824-cb99058d5e15>
+Date:   Wed Aug 5 15:38:32 2015 +0000
+
+    Fix buffer overflow for named references in (?| situations.
+
+    git-svn-id: svn://vcs.exim.org/pcre/code/trunk@1585 2f5784b3-3f2a-0410-8824-cb99058d5e15
+
+Signed-off-by: Petr Písař <ppisar@redhat.com>
+---
+ pcre_compile.c       | 74 ++++++++++++++++++++++++++++++----------------------
+ pcre_internal.h      |  1 +
+ testdata/testinput2  |  2 ++
+ testdata/testoutput2 |  2 ++
+ 4 files changed, 48 insertions(+), 31 deletions(-)
+
+diff --git a/pcre_compile.c b/pcre_compile.c
+index f5d2384..5fe5c1d 100644
+--- a/pcre_compile.c
++++ b/pcre_compile.c
+@@ -6641,6 +6641,7 @@ for (;; ptr++)
+         /* ------------------------------------------------------------ */
+         case CHAR_VERTICAL_LINE:  /* Reset capture count for each branch */
+         reset_bracount = TRUE;
++        cd->dupgroups = TRUE;     /* Record (?| encountered */ 
+         /* Fall through */
+         /* ------------------------------------------------------------ */
+@@ -7151,7 +7152,8 @@ for (;; ptr++)
+         if (lengthptr != NULL)
+           {
+           named_group *ng;
+-
++          recno = 0;
++           
+           if (namelen == 0)
+             {
+             *errorcodeptr = ERR62;
+@@ -7168,32 +7170,6 @@ for (;; ptr++)
+             goto FAILED;
+             }
+-          /* The name table does not exist in the first pass; instead we must
+-          scan the list of names encountered so far in order to get the
+-          number. If the name is not found, set the value to 0 for a forward
+-          reference. */
+-
+-          recno = 0;
+-          ng = cd->named_groups;
+-          for (i = 0; i < cd->names_found; i++, ng++)
+-            {
+-            if (namelen == ng->length &&
+-                STRNCMP_UC_UC(name, ng->name, namelen) == 0)
+-              {
+-              open_capitem *oc;
+-              recno = ng->number;
+-              if (is_recurse) break;
+-              for (oc = cd->open_caps; oc != NULL; oc = oc->next)
+-                {
+-                if (oc->number == recno)
+-                  {
+-                  oc->flag = TRUE;
+-                  break;
+-                  }
+-                }
+-              }
+-            }
+-
+           /* Count named back references. */
+           if (!is_recurse) cd->namedrefcount++;
+@@ -7215,7 +7191,44 @@ for (;; ptr++)
+           issue is fixed "properly" in PCRE2. As PCRE1 is now in maintenance
+           only mode, we finesse the bug by allowing more memory always. */
+-          /* if (recno == 0) */ *lengthptr += 2 + 2*LINK_SIZE;
++          *lengthptr += 2 + 2*LINK_SIZE;
++          
++          /* It is even worse than that. The current reference may be to an
++          existing named group with a different number (so apparently not
++          recursive) but which later on is also attached to a group with the
++          current number. This can only happen if $(| has been previous 
++          encountered. In that case, we allow yet more memory, just in case. 
++          (Again, this is fixed "properly" in PCRE2. */
++          
++          if (cd->dupgroups) *lengthptr += 2 + 2*LINK_SIZE;
++
++          /* Otherwise, check for recursion here. The name table does not exist
++          in the first pass; instead we must scan the list of names encountered
++          so far in order to get the number. If the name is not found, leave
++          the value of recno as 0 for a forward reference. */
++           
++          else
++            { 
++            ng = cd->named_groups;
++            for (i = 0; i < cd->names_found; i++, ng++)
++              {
++              if (namelen == ng->length &&
++                  STRNCMP_UC_UC(name, ng->name, namelen) == 0)
++                {
++                open_capitem *oc;
++                recno = ng->number;
++                if (is_recurse) break;
++                for (oc = cd->open_caps; oc != NULL; oc = oc->next)
++                  {
++                  if (oc->number == recno)
++                    {
++                    oc->flag = TRUE;
++                    break;
++                    }
++                  }
++                }
++              }
++            }   
+           }
+         /* In the real compile, search the name table. We check the name
+@@ -7262,8 +7275,6 @@ for (;; ptr++)
+           for (i++; i < cd->names_found; i++)
+             {
+             if (STRCMP_UC_UC(slot + IMM2_SIZE, cslot + IMM2_SIZE) != 0) break;
+-
+-
+             count++;
+             cslot += cd->name_entry_size;
+             }
+@@ -9189,6 +9200,7 @@ cd->names_found = 0;
+ cd->name_entry_size = 0;
+ cd->name_table = NULL;
+ cd->dupnames = FALSE;
++cd->dupgroups = FALSE;
+ cd->namedrefcount = 0;
+ cd->start_code = cworkspace;
+ cd->hwm = cworkspace;
+@@ -9223,7 +9235,7 @@ if (errorcode != 0) goto PCRE_EARLY_ERROR_RETURN;
+ DPRINTF(("end pre-compile: length=%d workspace=%d\n", length,
+   (int)(cd->hwm - cworkspace)));
+-
++  
+ if (length > MAX_PATTERN_SIZE)
+   {
+   errorcode = ERR20;
+diff --git a/pcre_internal.h b/pcre_internal.h
+index dd0ac7f..7ca6020 100644
+--- a/pcre_internal.h
++++ b/pcre_internal.h
+@@ -2446,6 +2446,7 @@ typedef struct compile_data {
+   BOOL had_pruneorskip;             /* (*PRUNE) or (*SKIP) encountered */
+   BOOL check_lookbehind;            /* Lookbehinds need later checking */
+   BOOL dupnames;                    /* Duplicate names exist */
++  BOOL dupgroups;                   /* Duplicate groups exist: (?| found */ 
+   BOOL iscondassert;                /* Next assert is a condition */
+   int  nltype;                      /* Newline type */
+   int  nllen;                       /* Newline string length */
+diff --git a/testdata/testinput2 b/testdata/testinput2
+index e12de3a..8e044f8 100644
+--- a/testdata/testinput2
++++ b/testdata/testinput2
+@@ -4158,4 +4158,6 @@ backtracking verbs. --/
+ "(?J:(?|(?'R')(\k'R')|((?'R'))))"
++/(?J:(?|(:(?|(?'R')(\k'R')|((?'R')))H'Rk'Rf)|s(?'R')))/
++
+ /-- End of testinput2 --/
+diff --git a/testdata/testoutput2 b/testdata/testoutput2
+index 5bad26c..6019425 100644
+--- a/testdata/testoutput2
++++ b/testdata/testoutput2
+@@ -14430,4 +14430,6 @@ Failed: unmatched parentheses at offset 23
+ "(?J:(?|(?'R')(\k'R')|((?'R'))))"
++/(?J:(?|(:(?|(?'R')(\k'R')|((?'R')))H'Rk'Rf)|s(?'R')))/
++
+ /-- End of testinput2 --/
+-- 
+2.4.3
+
diff --git a/src/patches/pcre-8.37-Fix-named-forward-reference-to-duplicate-group-numbe.patch b/src/patches/pcre-8.37-Fix-named-forward-reference-to-duplicate-group-numbe.patch
new file mode 100644 (file)
index 0000000..837e86f
--- /dev/null
@@ -0,0 +1,98 @@
+From 83ed574998fe7b844b98ab7cd56291068feb9e31 Mon Sep 17 00:00:00 2001
+From: ph10 <ph10@2f5784b3-3f2a-0410-8824-cb99058d5e15>
+Date: Sat, 16 May 2015 11:05:40 +0000
+Subject: [PATCH] Fix named forward reference to duplicate group number
+ overflow bug.
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Port to 8.37:
+
+commit 2fa78aa4e42bcebf2d616c4ee89c012f29dc3447
+Author: ph10 <ph10@2f5784b3-3f2a-0410-8824-cb99058d5e15>
+Date:   Sat May 16 11:05:40 2015 +0000
+
+    Fix named forward reference to duplicate group number overflow bug.
+
+    git-svn-id: svn://vcs.exim.org/pcre/code/trunk@1559 2f5784b3-3f2a-0410-8824-cb99058d5e15
+
+Signed-off-by: Petr Písař <ppisar@redhat.com>
+---
+ pcre_compile.c       | 24 ++++++++++++++++--------
+ testdata/testinput1  |  3 +++
+ testdata/testoutput1 |  5 +++++
+ 3 files changed, 24 insertions(+), 8 deletions(-)
+
+diff --git a/pcre_compile.c b/pcre_compile.c
+index b66b1f6..8b4aaef 100644
+--- a/pcre_compile.c
++++ b/pcre_compile.c
+@@ -7183,15 +7183,15 @@ for (;; ptr++)
+               open_capitem *oc;
+               recno = ng->number;
+               if (is_recurse) break;
+-              for (oc = cd->open_caps; oc != NULL; oc = oc->next)         
+-                {          
+-                if (oc->number == recno)                                     
+-                  {               
+-                  oc->flag = TRUE;                                      
++              for (oc = cd->open_caps; oc != NULL; oc = oc->next)
++                {
++                if (oc->number == recno)
++                  {
++                  oc->flag = TRUE;
+                   break;
+-                  }                                                         
+-                }                          
+-              }    
++                  }
++                }
++              }
+             }
+           /* Count named back references. */
+@@ -7203,6 +7203,14 @@ for (;; ptr++)
+           16-bit data item. */
+           *lengthptr += IMM2_SIZE;
++
++          /* If this is a forward reference and we are within a (?|...) group,
++          the reference may end up as the number of a group which we are
++          currently inside, that is, it could be a recursive reference. In the
++          real compile this will be picked up and the reference wrapped with
++          OP_ONCE to make it atomic, so we must space in case this occurs. */
++
++          if (recno == 0) *lengthptr += 2 + 2*LINK_SIZE;
+           }
+         /* In the real compile, search the name table. We check the name
+diff --git a/testdata/testinput1 b/testdata/testinput1
+index 73c2f4d..8379ce0 100644
+--- a/testdata/testinput1
++++ b/testdata/testinput1
+@@ -5730,4 +5730,7 @@ AbcdCBefgBhiBqz
+ "(?1)(?#?'){8}(a)"
+     baaaaaaaaac
++"(?|(\k'Pm')|(?'Pm'))"
++    abcd
++
+ /-- End of testinput1 --/
+diff --git a/testdata/testoutput1 b/testdata/testoutput1
+index 0a53fd0..e852ab9 100644
+--- a/testdata/testoutput1
++++ b/testdata/testoutput1
+@@ -9429,4 +9429,9 @@ No match
+  0: aaaaaaaaa
+  1: a
++"(?|(\k'Pm')|(?'Pm'))"
++    abcd
++ 0: 
++ 1: 
++
+ /-- End of testinput1 --/
+-- 
+2.4.3
+