<pierre.vi...@postfinance.ch> writes:

>> I noticed that your proxy is changing the status line by dropping the
>> reason-phrase:
>> 
>>    HTTP/1.1 207 Multi-Status
>> 
>> to
>> 
>>    HTTP/1.1 207

> Good news!  I could create a new implementation of the JDK HttpServer
> which fixes the 207 Status line problem, and I can't reproduce the
> segmentation fault anymore when the HttpProxy uses this fixed version.

Looking at serf's response_buckets.c it doesn't handle a malformed
status line like

    HTTP/1.1 207

That passes the apr_date_checkmask check:

    /* ctx->linebuf.line should be of form: HTTP/1.1 200 OK */
    res = apr_date_checkmask(ctx->linebuf.line, "HTTP/#.# ###*");
    if (!res) {
        /* Not an HTTP response?  Well, at least we won't understand it. */
        return SERF_ERROR_BAD_HTTP_RESPONSE;
    }

    ctx->sl.version = SERF_HTTP_VERSION(ctx->linebuf.line[5] - '0',
                                        ctx->linebuf.line[7] - '0');
    ctx->sl.code = apr_strtoi64(ctx->linebuf.line + 8, &reason, 10);

    /* Skip leading spaces for the reason string. */
    if (apr_isspace(*reason)) {
        reason++;
    }

    /* Copy the reason value out of the line buffer. */
    ctx->sl.reason = serf_bstrmemdup(allocator, reason,
                                     ctx->linebuf.used
                                     - (reason - ctx->linebuf.line));

After the apr_strtoi64 reason will point just beyond ctx->linebuf.used.
That's still within the buffer but *reason is arbitrary.  If it happens
to be whitespace then reason will be incremented and the value passed to
serf_bstrmemdup will be negative. That converts to a huge unsigned
value which causes a SEGV.

Two things need to change:

  - the mask needs to require at least one space after the status code

  - ctx->linebuf.used needs to be at least 13 before calling
    apr_date_checkmask.


Index: buckets/response_buckets.c
===================================================================
--- buckets/response_buckets.c  (revision 2445)
+++ buckets/response_buckets.c  (working copy)
@@ -129,7 +129,10 @@ static apr_status_t parse_status_line(response_con
     char *reason; /* ### stupid APR interface makes this non-const */
 
     /* ctx->linebuf.line should be of form: HTTP/1.1 200 OK */
-    res = apr_date_checkmask(ctx->linebuf.line, "HTTP/#.# ###*");
+    if (ctx->linebuf.used < 13) {
+        return SERF_ERROR_BAD_HTTP_RESPONSE;
+    }
+    res = apr_date_checkmask(ctx->linebuf.line, "HTTP/#.# ### *");
     if (!res) {
         /* Not an HTTP response?  Well, at least we won't understand it. */
         return SERF_ERROR_BAD_HTTP_RESPONSE;

-- 
Philip Martin | Subversion Committer
WANdisco // *Non-Stop Data*

Reply via email to