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 = "";