Package: libapreq2-3
Version: 2.13-5+b3
Severity: grave

libapreq's multipart parser can be made dereference the null pointer
by issuing a simple CURL command:

 curl http://a/b -F 'foo=bar;type=multipart/dummy'

This POSTs a "multipart/form-data" body where one part has the
Content-Type "multipart/dummy" (i.e. a nested "multipart"), which
enables this branch:

 if (ct != NULL && strncmp(ct, "multipart/", 10) == 0) {

 https://github.com/apache/apreq/blob/v2_13/library/parser_multipart.c#L401

Later, this calls create_multipart_context() and dereferences the
returned pointer (without checking it):

 next_ctx = create_multipart_context(...
 next_ctx->param_name = "";

 https://github.com/apache/apreq/blob/v2_13/library/parser_multipart.c#L409-L414

The function create_multipart_context() however can return NULL if
there is no "boundary" attribute.  And omitting "boundary" is what my
CURL command does.

With this simple exploit, I can remotely crash any process which uses
libapreq2 only by issuing an invalid nested "multipart" body.  Since
this bug is remotely exploitable, I decided to set "grave" severity.

This bug affects all libapreq2 versions ever shipped in Debian, and
was introduced by SVN commit 227276 in 2005.  Prior to this commit,
there was a NULL check, but the commit removed it:

 
http://svn.apache.org/viewvc/httpd/apreq/trunk/library/parser_multipart.c?r1=227276&r2=227275&pathrev=227276

The attached patch fixes the bug by re-adding the NULL check.
commit f27d15e47000b0442e8071ab0fd76b82df9f2d2f
Author: Max Kellermann <max.kellerm...@gmail.com>
Date:   Tue Sep 10 12:15:07 2019 +0200

    parser_multipart: fix NULL pointer dereference in nested multipart
    
    create_multipart_context() can return NULL if the given Content-Type
    was not recognized (if there is no "boundary" attribute).  This
    crashes libapreq2.
    
    This bug was introduced by SVN commit 227276.  Prior to this commit,
    there was a NULL check, but the commit removed it:
    
     http://svn.apache.org/viewvc/httpd/apreq/trunk/library/parser_multipart.c?r1=227276&r2=227275&pathrev=227276

diff --git a/library/parser_multipart.c b/library/parser_multipart.c
index 60b5bad..4242b7e 100644
--- a/library/parser_multipart.c
+++ b/library/parser_multipart.c
@@ -410,6 +410,10 @@ APREQ_DECLARE_PARSER(apreq_parse_multipart)
                                                     parser->brigade_limit,
                                                     parser->temp_dir,
                                                     ctx->level + 1);
+                if (next_ctx == NULL) {
+                    ctx->status = MFD_ERROR;
+                    goto mfd_parse_brigade;
+                }
 
                 next_ctx->param_name = "";
 

Reply via email to