Wietse, Viktor

It seems that this is the problematic part of the pcre pattern

>
/^Content-(Disposition|Type).*name\s*=\s*("(?:[^"]|\\")*|[^();:,\/<>\@\"?=<>\[\]\
]*)

I tested by replacing star by star with explicit limits and found that
limits avoid the segfault. I replaced the last two stars with limits up
to 10000 chars

>
/^Content-(Disposition|Type).*name\s*=\s*("(?:[^"]|\\"){0,10000}|[^();:,\/<>\@\"?=<>\[\]\
]{0,10000})

no segfault but I think the whole header has not been processed as its
longer than 10'000 chars. Tried with higher values than 10000 but then
postmap issues a warning that the number is too big.

> postmap: warning: pcre map /etc/postfix/mime_header_checks.pcre, line
21: error in regex at offset 63: number too big in {} quantifier

After solving the "too big number" issue postmap said that the pcre
pattern is too big :-)

> postmap: warning: pcre map /etc/postfix/mime_header_checks.pcre, line
21: error in regex at offset 352: regular expression is too large


So the problem is definitely our pattern in combination with a VERY big
mime part header. We're on introducing limits where we can in our patterns.
Anyway I think that this should not end in such an ugly error where
postfix cleanup goes south because of such header/pattern combination.


--
Cheers

tobi

Am 14.05.20 um 09:13 schrieb Viktor Dukhovni:
> On Thu, May 14, 2020 at 08:53:42AM +0200, Tobi wrote:
> 
>> using your suggestion with valgrind I found that the main-stacksize
>> seems to be the problem. By using --main-stacksize with different values
>> I found that the last working value is 59449345, changing to ...344 let
>> postmap segfault:
> 
> But whatever the stacksize, the PCRE library must not segfault.  We need
> to be sure that it returns an error to the caller, rather than blows up.
> 
>>> ==7988== Stack overflow in thread #1: can't grow stack to 0x1ffb74f000
>>
>> We will try allowing more stacksize by /etc/security/limits.conf to
>> postfix and re-design our pcre pattern(s) to avoid (where possible) the
>> usage of .* without any limits :-)
> 
> Keeping your (ir)regular expressions simpler is always a good idea.
> Especially avoid costly use of multiple '.*' patterns in the same
> expression.  Not a good idea:
>     
>     /a.*b.*c.*d.*...z/
> 
> Perhaps there's something we can do with default resource limits.
> From the pcre2pattern(2) manpage:
>  
>    Setting match resource limits
> 
>        The pcre2_match() function contains a counter that is incremented
>        every time it goes round its main loop. The caller of
>        pcre2_match() can set a limit on this counter, which  therefore
>        limits  the  amount  of  computing resource used for a match. The
>        maximum depth of nested backtracking can also be limited; this
>        indirectly restricts the amount of heap memory that is used, but
>        there is also an explicit memory limit that can be set.
> 
>        These facilities are provided to catch runaway matches that are
>        provoked by patterns with huge matching trees. A common example
>        is a pattern with nested unlimited repeats applied to a long
>        string that does not match. When one of these limits is reached,
>        pcre2_match() gives an error return. The limits can also be set
>        by items at the start of the pattern of the form
> 
>          (*LIMIT_HEAP=d)
>          (*LIMIT_MATCH=d)
>          (*LIMIT_DEPTH=d)
> 
>        where  d is any number of decimal digits. However, the value of
>        the setting must be less than the value set (or defaulted) by the
>        caller of pcre2_match() for it to have any effect. In other
>        words, the pattern writer can lower the limits set by the
>        programmer, but not raise them. If there is more than one setting
>        of one of these limits, the lower value is used.  The heap limit
>        is specified in kibibytes (units of 1024 bytes).
> 
>        Prior to release 10.30, LIMIT_DEPTH was called LIMIT_RECURSION.
>        This name is still recognized for backwards compatibility.
> 
>        The  heap limit applies only when the pcre2_match() or
>        pcre2_dfa_match() interpreters are used for matching. It does not
>        apply to JIT. The match limit is used (but in a different way)
>        when JIT is being used, or when pcre2_dfa_match() is called, to
>        limit computing resource usage by those matching functions. The
>        depth limit is ignored by JIT but is relevant  for  DFA matching,
>        which  uses  function  recursion for recursions within the
>        pattern and for lookaround assertions and atomic groups. In this
>        case, the depth limit controls the depth of such recursion.
> 

Reply via email to