Package pcre3 Tags 324531 +patch thanks Martin Pitt wrote on 24/08/2005 14:12: > Here is the relevant change from pcre3 6.1-> 6.2, ported to 5.0: > > http://patches.ubuntu.com/patches/pcre3.CAN-2005-2491.diff
Hmm, didn't get that the capturing fix is also needed. But your are right there. Attached are the patches which also include that capture-related fix (4.5 and 5.0. The patch to 3.4 doesn't include anything to that part, since it doesn't seem vulnerable to the capturing problem (and uses a different approach to capturing anyway). I also didn't include the patches made to the testing suite of the package, since they by themself are not part of the security problem. All three packages compile fine after the patches were applied. Functionality also seems to be fine. regards, Sven
diff -ur pcre3-3.4.orig/pcre.c pcre3-3.4/pcre.c --- pcre3-3.4.orig/pcre.c 2000-08-22 11:05:43.000000000 +0200 +++ pcre3-3.4/pcre.c 2005-08-24 15:16:05.140911310 +0200 @@ -711,7 +711,18 @@ int min = 0; int max = -1; +/* Read the minimum value and do a paranoid check: a negative value indicates +an integer overflow. */ + while ((cd->ctypes[*p] & ctype_digit) != 0) min = min * 10 + *p++ - '0'; +if (min < 0 || min > 65535) + { + *errorptr = ERR5; + return p; + } + +/* Read the maximum value if there is one, and again do a paranoid on its size. +Also, max must not be less than min. */ if (*p == '}') max = min; else { @@ -719,6 +730,11 @@ { max = 0; while((cd->ctypes[*p] & ctype_digit) != 0) max = max * 10 + *p++ - '0'; + if (max < 0 || max > 65535) + { + *errorptr = ERR5; + return p; + } if (max < min) { *errorptr = ERR4; @@ -727,16 +743,11 @@ } } -/* Do paranoid checks, then fill in the required variables, and pass back the -pointer to the terminating '}'. */ +/* Fill in the required variables, and pass back the pointer to the terminating +'}'. */ -if (min > 65535 || max > 65535) - *errorptr = ERR5; -else - { - *minp = min; - *maxp = max; - } +*minp = min; +*maxp = max; return p; }
diff -ur pcre3-4.5.orig/pcre.c pcre3-4.5/pcre.c --- pcre3-4.5.orig/pcre.c 2003-12-10 17:45:44.000000000 +0100 +++ pcre3-4.5/pcre.c 2005-08-24 15:25:17.580242557 +0200 @@ -1047,7 +1047,18 @@ int min = 0; int max = -1; +/* Read the minimum value and do a paranoid check: a negative value indicates +an integer overflow. */ + while ((digitab[*p] & ctype_digit) != 0) min = min * 10 + *p++ - '0'; +if (min < 0 || min > 65535) + { + *errorptr = ERR5; + return p; + } + +/* Read the maximum value if there is one, and again do a paranoid on its size. +Also, max must not be less than min. */ if (*p == '}') max = min; else { @@ -1055,6 +1066,11 @@ { max = 0; while((digitab[*p] & ctype_digit) != 0) max = max * 10 + *p++ - '0'; + if (max < 0 || max > 65535) + { + *errorptr = ERR5; + return p; + } if (max < min) { *errorptr = ERR4; @@ -1063,16 +1079,11 @@ } } -/* Do paranoid checks, then fill in the required variables, and pass back the -pointer to the terminating '}'. */ +/* Fill in the required variables, and pass back the pointer to the terminating +'}'. */ -if (min > 65535 || max > 65535) - *errorptr = ERR5; -else - { - *minp = min; - *maxp = max; - } +*minp = min; +*maxp = max; return p; } @@ -4113,6 +4124,7 @@ BOOL class_utf8; #endif BOOL inescq = FALSE; +BOOL capturing; unsigned int brastackptr = 0; size_t size; uschar *code; @@ -4528,6 +4540,7 @@ case '(': branch_newextra = 0; bracket_length = 1 + LINK_SIZE; + capturing = FALSE; /* Handle special forms of bracket, which all start (? */ @@ -4615,6 +4628,9 @@ case 'P': ptr += 3; + + /* Handle the definition of a named subpattern */ + if (*ptr == '<') { const uschar *p; /* Don't amalgamate; some compilers */ @@ -4627,9 +4643,12 @@ } name_count++; if (ptr - p > max_name_size) max_name_size = (ptr - p); + capturing = TRUE; /* Named parentheses are always capturing */ break; } + /* Handle back references and recursive calls to named subpatterns */ + if (*ptr == '=' || *ptr == '>') { while ((compile_block.ctypes[*(++ptr)] & ctype_word) != 0); @@ -4804,18 +4823,24 @@ continue; } - /* If options were terminated by ':' control comes here. Fall through - to handle the group below. */ + /* If options were terminated by ':' control comes here. This is a + non-capturing group with an options change. There is nothing more that + needs to be done because "capturing" is already set FALSE by default; + we can just fall through. */ + } } - /* Extracting brackets must be counted so we can process escapes in a - Perlish way. If the number exceeds EXTRACT_BASIC_MAX we are going to - need an additional 3 bytes of store per extracting bracket. However, if - PCRE_NO_AUTO)CAPTURE is set, unadorned brackets become non-capturing, so we - must leave the count alone (it will aways be zero). */ + /* Ordinary parentheses, not followed by '?', are capturing unless + PCRE_NO_AUTO_CAPTURE is set. */ + + else capturing = (options & PCRE_NO_AUTO_CAPTURE) == 0; + + /* Capturing brackets must be counted so we can process escapes in a + Perlish way. If the number exceeds EXTRACT_BASIC_MAX we are going to need + an additional 3 bytes of memory per capturing bracket. */ - else if ((options & PCRE_NO_AUTO_CAPTURE) == 0) + if (capturing) { bracount++; if (bracount > EXTRACT_BASIC_MAX) bracket_length += 3; Only in pcre3-4.5: pcre.c.orig Only in pcre3-4.5: pcre.c.rej
diff -ur pcre3-5.0.orig/pcre.c pcre3-5.0/pcre.c --- pcre3-5.0.orig/pcre.c 2004-09-13 16:20:00.000000000 +0200 +++ pcre3-5.0/pcre.c 2005-08-24 15:27:25.960768783 +0200 @@ -1245,7 +1245,18 @@ int min = 0; int max = -1; +/* Read the minimum value and do a paranoid check: a negative value indicates +an integer overflow. */ + while ((digitab[*p] & ctype_digit) != 0) min = min * 10 + *p++ - '0'; +if (min < 0 || min > 65535) + { + *errorptr = ERR5; + return p; + } + +/* Read the maximum value if there is one, and again do a paranoid on its size. +Also, max must not be less than min. */ if (*p == '}') max = min; else { @@ -1253,6 +1264,11 @@ { max = 0; while((digitab[*p] & ctype_digit) != 0) max = max * 10 + *p++ - '0'; + if (max < 0 || max > 65535) + { + *errorptr = ERR5; + return p; + } if (max < min) { *errorptr = ERR4; @@ -1261,16 +1277,11 @@ } } -/* Do paranoid checks, then fill in the required variables, and pass back the -pointer to the terminating '}'. */ +/* Fill in the required variables, and pass back the pointer to the terminating +'}'. */ -if (min > 65535 || max > 65535) - *errorptr = ERR5; -else - { - *minp = min; - *maxp = max; - } +*minp = min; +*maxp = max; return p; } @@ -4475,6 +4486,7 @@ BOOL class_utf8; #endif BOOL inescq = FALSE; +BOOL capturing; unsigned int brastackptr = 0; size_t size; uschar *code; @@ -5021,6 +5033,7 @@ case '(': branch_newextra = 0; bracket_length = 1 + LINK_SIZE; + capturing = FALSE; /* Handle special forms of bracket, which all start (? */ @@ -5108,6 +5121,9 @@ case 'P': ptr += 3; + + /* Handle the definition of a named subpattern */ + if (*ptr == '<') { const uschar *p; /* Don't amalgamate; some compilers */ @@ -5120,9 +5136,12 @@ } name_count++; if (ptr - p > max_name_size) max_name_size = (ptr - p); + capturing = TRUE; /* Named parentheses are always capturing */ break; } + /* Handle back references and recursive calls to named subpatterns */ + if (*ptr == '=' || *ptr == '>') { while ((compile_block.ctypes[*(++ptr)] & ctype_word) != 0); @@ -5297,18 +5316,24 @@ continue; } - /* If options were terminated by ':' control comes here. Fall through - to handle the group below. */ + /* If options were terminated by ':' control comes here. This is a + non-capturing group with an options change. There is nothing more that + needs to be done because "capturing" is already set FALSE by default; + we can just fall through. */ + } } - /* Extracting brackets must be counted so we can process escapes in a - Perlish way. If the number exceeds EXTRACT_BASIC_MAX we are going to - need an additional 3 bytes of store per extracting bracket. However, if - PCRE_NO_AUTO)CAPTURE is set, unadorned brackets become non-capturing, so we - must leave the count alone (it will aways be zero). */ + /* Ordinary parentheses, not followed by '?', are capturing unless + PCRE_NO_AUTO_CAPTURE is set. */ + + else capturing = (options & PCRE_NO_AUTO_CAPTURE) == 0; + + /* Capturing brackets must be counted so we can process escapes in a + Perlish way. If the number exceeds EXTRACT_BASIC_MAX we are going to need + an additional 3 bytes of memory per capturing bracket. */ - else if ((options & PCRE_NO_AUTO_CAPTURE) == 0) + if (capturing) { bracount++; if (bracount > EXTRACT_BASIC_MAX) bracket_length += 3; Only in pcre3-5.0: pcre.c.orig