Bug#939937: Remotely exploitable null pointer dereference bug

2019-09-30 Thread Salvatore Bonaccorso
Hi

On Tue, Sep 10, 2019 at 12:23:04PM +0200, Max Kellermann wrote:
> 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.

This issue has been assigned CVE-2019-12412.

Regards,
Salvatore



Bug#939937: Remotely exploitable null pointer dereference bug

2019-09-10 Thread Max Kellermann
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 
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 = "";