Dan Lists:
> > The PCRE client does not know the queue ID, and the SMTP daemon
> > does not know that the PCRE client aborted (nor does the SMTP daemon
> > know why).  This will not change. Logging the full execution context
> > for every possible error comes with a significant cost.
> >
> 
> cleanup knows the queue id, it logged:

The PCRE CLIENT does not know the queue ID, and it is the PCRE
client that reports the error. 

It is possible to change the fatal error into a warning, and to
return a "table lookup error" to the body_checks function. In that
case the body_checks function will log the queue ID; that code
already exists.

With the patch below, the fatal error becomes a warning, and the
logging becomes like this:

    warning: pcre map xxx, line yyy: backtracking limit exceeded

    warning: queueid: body_checks map lookup problem -- message not
        accepted, try again later

In the first message, the PCRE client does not know the queue ID,
but it knows why the lookup failed.

In the second message, the body_checks function that asked for the
table lookup only knows that lookup failed, but it does not know why. 

That is as good as it gets without major internal changes to Postfix.

> > Maybe this helps:
> > https://groups.google.com/forum/#!topic/mailing.postfix.users/14GV4g4kNyk
> 
> My expression does not have any .* in it.  Here it is:
> 
> %https?://[0-9]*\.[0-9]*\.[0-9]*\.[0-9]*/public/% REJECT

According to PCRE documentation, the error means that PCRE gave up
after calling the matcher too many times (10 million times is the
built-in default). This means that the text of the Postfix error
message was incorrect, and I have changed it in the patch below.

In your PCRE pattern you could safely use "[0-9]+" instead of
"[0-9]*" and cut down the amount of recursion and backtracking,
thereby reducing the likelihood of running into the limit.

> can I bump the limit?

PCRE has an API to increase the 10 million to a larger number, but
it is not used by Postfix. You might have to increase it into the
billions, and that could get you into DOS-able territory.

        Wietse

--- /var/tmp/postfix-3.1-20151003/src/util/dict_pcre.c  2014-12-06 
20:35:32.000000000 -0500
+++ src/util/dict_pcre.c        2015-10-11 12:48:43.000000000 -0400
@@ -217,41 +217,48 @@
 static void dict_pcre_exec_error(const char *mapname, int lineno, int errval)
 {
     switch (errval) {
-       case 0:
+    case 0:
        msg_warn("pcre map %s, line %d: too many (...)",
                 mapname, lineno);
        return;
     case PCRE_ERROR_NULL:
     case PCRE_ERROR_BADOPTION:
-       msg_fatal("pcre map %s, line %d: bad args to re_exec",
-                 mapname, lineno);
+       msg_warn("pcre map %s, line %d: bad args to re_exec",
+                mapname, lineno);
+       return;
     case PCRE_ERROR_BADMAGIC:
     case PCRE_ERROR_UNKNOWN_NODE:
-       msg_fatal("pcre map %s, line %d: corrupt compiled regexp",
-                 mapname, lineno);
+       msg_warn("pcre map %s, line %d: corrupt compiled regexp",
+                mapname, lineno);
+       return;
 #ifdef PCRE_ERROR_NOMEMORY
     case PCRE_ERROR_NOMEMORY:
-       msg_fatal("pcre map %s, line %d: out of memory",
-                 mapname, lineno);
+       msg_warn("pcre map %s, line %d: out of memory",
+                mapname, lineno);
+       return;
 #endif
 #ifdef PCRE_ERROR_MATCHLIMIT
     case PCRE_ERROR_MATCHLIMIT:
-       msg_fatal("pcre map %s, line %d: matched text exceeds buffer limit",
-                 mapname, lineno);
+       msg_warn("pcre map %s, line %d: backtracking limit exceeded",
+                mapname, lineno);
+       return;
 #endif
 #ifdef PCRE_ERROR_BADUTF8
     case PCRE_ERROR_BADUTF8:
-       msg_fatal("pcre map %s, line %d: bad UTF-8 sequence in search string",
-                 mapname, lineno);
+       msg_warn("pcre map %s, line %d: bad UTF-8 sequence in search string",
+                mapname, lineno);
+       return;
 #endif
 #ifdef PCRE_ERROR_BADUTF8_OFFSET
     case PCRE_ERROR_BADUTF8_OFFSET:
-       msg_fatal("pcre map %s, line %d: bad UTF-8 start offset in search 
string",
-                 mapname, lineno);
+       msg_warn("pcre map %s, line %d: bad UTF-8 start offset in search 
string",
+                mapname, lineno);
+       return;
 #endif
     default:
-       msg_fatal("pcre map %s, line %d: unknown re_exec error: %d",
-                 mapname, lineno, errval);
+       msg_warn("pcre map %s, line %d: unknown re_exec error: %d",
+                mapname, lineno, errval);
+       return;
     }
 }
 
@@ -310,7 +317,8 @@
                                                 * match */
            } else {
                dict_pcre_exec_error(dict->name, rule->lineno, ctxt.matches);
-               continue;                       /* pcre_exec failed */
+               dict->error = DICT_ERR_CONFIG;
+               return (0);
            }
 
            /*
@@ -361,7 +369,8 @@
                                                 * match */
            } else {
                dict_pcre_exec_error(dict->name, rule->lineno, ctxt.matches);
-               continue;                       /* pcre_exec failed */
+               dict->error = DICT_ERR_CONFIG;
+               return (0);
            }
            nesting++;
            continue;

Reply via email to