Message ID | 4880577cbd16ccf732daf804bb720373c3a4de05.camel@lists.verisure.com |
---|---|
State | New |
Headers | show |
Series | [meta-oe,dunfell] libmicrohttpd: Add patch to fix CVE-2021-3466 | expand |
On Tue, 2021-12-21 at 14:29 -0800, akuster808 wrote: > Ernst, > > On 12/21/21 5:09 AM, Ernst Sjöstrand wrote: > > Extract patch from the 0.9.71 release commit. > Does this affect any other branch ? What version does it affect? Only version 0.9.70 is vulnerable, and gatesgarth has 0.9.71. > > Signed-off-by: Ernst Sjöstrand <ernst.sjostrand@verisure.com> > > --- > > .../libmicrohttpd/CVE-2021-3466.patch | 152 ++++++++++++++++++ > > .../libmicrohttpd/libmicrohttpd_0.9.70.bb | 3 +- > > 2 files changed, 154 insertions(+), 1 deletion(-) > > create mode 100644 meta-oe/recipes-support/libmicrohttpd/libmicrohttpd/CVE- > > 2021-3466.patch > > > > diff --git a/meta-oe/recipes-support/libmicrohttpd/libmicrohttpd/CVE-2021- > > 3466.patch b/meta-oe/recipes-support/libmicrohttpd/libmicrohttpd/CVE-2021- > > 3466.patch > > new file mode 100644 > > index 000000000..8c36c2263 > > --- /dev/null > > +++ b/meta-oe/recipes-support/libmicrohttpd/libmicrohttpd/CVE-2021- > > 3466.patch > > @@ -0,0 +1,152 @@ > > +From 86d9a61be6395220714b1a50d5144e65668961f6 Mon Sep 17 00:00:00 2001 > > +From: =?UTF-8?q?Ernst=20Sj=C3=B6strand?= <ernst.sjostrand@verisure.com> > > +Date: Tue, 21 Dec 2021 11:05:22 +0000 > > +Subject: [PATCH] Fix buffer overflow in url parser and add test > > + > > +Fixes CVE-2021-3466 > > Also the patch itself is missing; > > Upstream-Status: (Backport ?) > CVE: CVE-2021-3466 > Signed-off-by: Ernst Sjöstrand <ernst.sjostrand@verisure.com> > I'll send a v2. > -armin > > +--- > > + src/microhttpd/postprocessor.c | 18 ++++++-- > > + src/microhttpd/test_postprocessor.c | 66 +++++++++++++++++++++++++++++ > > + 2 files changed, 80 insertions(+), 4 deletions(-) > > + > > +diff --git a/src/microhttpd/postprocessor.c > > b/src/microhttpd/postprocessor.c > > +index b7f6b10..ebd1686 100644 > > +--- a/src/microhttpd/postprocessor.c > > ++++ b/src/microhttpd/postprocessor.c > > +@@ -137,8 +137,7 @@ struct MHD_PostProcessor > > + void *cls; > > + > > + /** > > +- * Encoding as given by the headers of the > > +- * connection. > > ++ * Encoding as given by the headers of the connection. > > + */ > > + const char *encoding; > > + > > +@@ -586,7 +585,7 @@ post_process_urlencoded (struct MHD_PostProcessor *pp, > > + pp->state = PP_Error; > > + break; > > + case PP_Callback: > > +- if ( (pp->buffer_pos + (end_key - start_key) > > > ++ if ( (pp->buffer_pos + (end_key - start_key) >= > > + pp->buffer_size) || > > + (pp->buffer_pos + (end_key - start_key) < > > + pp->buffer_pos) ) > > +@@ -636,6 +635,11 @@ post_process_urlencoded (struct MHD_PostProcessor *pp, > > + { > > + if (NULL == end_key) > > + end_key = &post_data[poff]; > > ++ if (pp->buffer_pos + (end_key - start_key) >= pp->buffer_size) > > ++ { > > ++ pp->state = PP_Error; > > ++ return MHD_NO; > > ++ } > > + memcpy (&kbuf[pp->buffer_pos], > > + start_key, > > + end_key - start_key); > > +@@ -663,6 +667,11 @@ post_process_urlencoded (struct MHD_PostProcessor *pp, > > + last_escape); > > + pp->must_ikvi = false; > > + } > > ++ if (PP_Error == pp->state) > > ++ { > > ++ /* State in error, returning failure */ > > ++ return MHD_NO; > > ++ } > > + return MHD_YES; > > + } > > + > > +@@ -1424,7 +1433,8 @@ MHD_destroy_post_processor (struct MHD_PostProcessor > > *pp) > > + the post-processing may have been interrupted > > + at any stage */ > > + if ( (pp->xbuf_pos > 0) || > > +- (pp->state != PP_Done) ) > > ++ ( (pp->state != PP_Done) && > > ++ (pp->state != PP_Init) ) ) > > + ret = MHD_NO; > > + else > > + ret = MHD_YES; > > +diff --git a/src/microhttpd/test_postprocessor.c > > b/src/microhttpd/test_postprocessor.c > > +index 2c37565..cba486d 100644 > > +--- a/src/microhttpd/test_postprocessor.c > > ++++ b/src/microhttpd/test_postprocessor.c > > +@@ -451,6 +451,71 @@ test_empty_value (void) > > + } > > + > > + > > ++static enum MHD_Result > > ++value_checker2 (void *cls, > > ++ enum MHD_ValueKind kind, > > ++ const char *key, > > ++ const char *filename, > > ++ const char *content_type, > > ++ const char *transfer_encoding, > > ++ const char *data, > > ++ uint64_t off, > > ++ size_t size) > > ++{ > > ++ return MHD_YES; > > ++} > > ++ > > ++ > > ++static int > > ++test_overflow () > > ++{ > > ++ struct MHD_Connection connection; > > ++ struct MHD_HTTP_Header header; > > ++ struct MHD_PostProcessor *pp; > > ++ size_t i; > > ++ size_t j; > > ++ size_t delta; > > ++ char *buf; > > ++ > > ++ memset (&connection, 0, sizeof (struct MHD_Connection)); > > ++ memset (&header, 0, sizeof (struct MHD_HTTP_Header)); > > ++ connection.headers_received = &header; > > ++ header.header = MHD_HTTP_HEADER_CONTENT_TYPE; > > ++ header.value = MHD_HTTP_POST_ENCODING_FORM_URLENCODED; > > ++ header.header_size = strlen (header.header); > > ++ header.value_size = strlen (header.value); > > ++ header.kind = MHD_HEADER_KIND; > > ++ for (i = 128; i < 1024 * 1024; i += 1024) > > ++ { > > ++ pp = MHD_create_post_processor (&connection, > > ++ 1024, > > ++ &value_checker2, > > ++ NULL); > > ++ buf = malloc (i); > > ++ if (NULL == buf) > > ++ return 1; > > ++ memset (buf, 'A', i); > > ++ buf[i / 2] = '='; > > ++ delta = 1 + (MHD_random_ () % (i - 1)); > > ++ j = 0; > > ++ while (j < i) > > ++ { > > ++ if (j + delta > i) > > ++ delta = i - j; > > ++ if (MHD_NO == > > ++ MHD_post_process (pp, > > ++ &buf[j], > > ++ delta)) > > ++ break; > > ++ j += delta; > > ++ } > > ++ free (buf); > > ++ MHD_destroy_post_processor (pp); > > ++ } > > ++ return 0; > > ++} > > ++ > > ++ > > + int > > + main (int argc, char *const *argv) > > + { > > +@@ -463,6 +528,7 @@ main (int argc, char *const *argv) > > + errorCount += test_multipart (); > > + errorCount += test_nested_multipart (); > > + errorCount += test_empty_value (); > > ++ errorCount += test_overflow (); > > + if (errorCount != 0) > > + fprintf (stderr, "Error (code: %u)\n", errorCount); > > + return errorCount != 0; /* 0 == pass */ > > diff --git a/meta-oe/recipes-support/libmicrohttpd/libmicrohttpd_0.9.70.bb > > b/meta-oe/recipes-support/libmicrohttpd/libmicrohttpd_0.9.70.bb > > index 94976d2e9..9d5e85e1a 100644 > > --- a/meta-oe/recipes-support/libmicrohttpd/libmicrohttpd_0.9.70.bb > > +++ b/meta-oe/recipes-support/libmicrohttpd/libmicrohttpd_0.9.70.bb > > @@ -7,7 +7,8 @@ SECTION = "net" > > DEPENDS = "file" > > > > SRC_URI = "${GNU_MIRROR}/libmicrohttpd/${BPN}-${PV}.tar.gz \ > > -" > > + file://CVE-2021-3466.patch \ > > + " > > SRC_URI[md5sum] = "dcd6045ecb4ea18c120afedccbd1da74" > > SRC_URI[sha256sum] = > > "90d0a3d396f96f9bc41eb0f7e8187796049285fabef82604acd4879590977307" > > > > > > -=-=-=-=-=-=-=-=-=-=-=- > > Links: You receive all messages sent to this group. > > View/Reply Online (#94466): > > https://urldefense.com/v3/__https://lists.openembedded.org/g/openembedded-devel/message/94466__;!!BFCLnRDDbM3FOmw!rOMP9VaDgUq33ddlZfmPANWR6K7C2lZdTg7hc4xqWfCLsvTaIpRAjppEA_rq2QLyX_a0uHGg1A$ > > > > Mute This Topic: > > https://urldefense.com/v3/__https://lists.openembedded.org/mt/87876647/3616698__;!!BFCLnRDDbM3FOmw!rOMP9VaDgUq33ddlZfmPANWR6K7C2lZdTg7hc4xqWfCLsvTaIpRAjppEA_rq2QLyX_a-1ysYQA$ > > > > Group Owner: openembedded-devel+owner@lists.openembedded.org > > Unsubscribe: > > https://urldefense.com/v3/__https://lists.openembedded.org/g/openembedded-devel/unsub__;!!BFCLnRDDbM3FOmw!rOMP9VaDgUq33ddlZfmPANWR6K7C2lZdTg7hc4xqWfCLsvTaIpRAjppEA_rq2QLyX_ZrBVyiTg$ > > [akuster808@gmail.com] > > -=-=-=-=-=-=-=-=-=-=-=- > >
diff --git a/meta-oe/recipes-support/libmicrohttpd/libmicrohttpd/CVE-2021-3466.patch b/meta-oe/recipes-support/libmicrohttpd/libmicrohttpd/CVE-2021-3466.patch new file mode 100644 index 000000000..8c36c2263 --- /dev/null +++ b/meta-oe/recipes-support/libmicrohttpd/libmicrohttpd/CVE-2021-3466.patch @@ -0,0 +1,152 @@ +From 86d9a61be6395220714b1a50d5144e65668961f6 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Ernst=20Sj=C3=B6strand?= <ernst.sjostrand@verisure.com> +Date: Tue, 21 Dec 2021 11:05:22 +0000 +Subject: [PATCH] Fix buffer overflow in url parser and add test + +Fixes CVE-2021-3466 +--- + src/microhttpd/postprocessor.c | 18 ++++++-- + src/microhttpd/test_postprocessor.c | 66 +++++++++++++++++++++++++++++ + 2 files changed, 80 insertions(+), 4 deletions(-) + +diff --git a/src/microhttpd/postprocessor.c b/src/microhttpd/postprocessor.c +index b7f6b10..ebd1686 100644 +--- a/src/microhttpd/postprocessor.c ++++ b/src/microhttpd/postprocessor.c +@@ -137,8 +137,7 @@ struct MHD_PostProcessor + void *cls; + + /** +- * Encoding as given by the headers of the +- * connection. ++ * Encoding as given by the headers of the connection. + */ + const char *encoding; + +@@ -586,7 +585,7 @@ post_process_urlencoded (struct MHD_PostProcessor *pp, + pp->state = PP_Error; + break; + case PP_Callback: +- if ( (pp->buffer_pos + (end_key - start_key) > ++ if ( (pp->buffer_pos + (end_key - start_key) >= + pp->buffer_size) || + (pp->buffer_pos + (end_key - start_key) < + pp->buffer_pos) ) +@@ -636,6 +635,11 @@ post_process_urlencoded (struct MHD_PostProcessor *pp, + { + if (NULL == end_key) + end_key = &post_data[poff]; ++ if (pp->buffer_pos + (end_key - start_key) >= pp->buffer_size) ++ { ++ pp->state = PP_Error; ++ return MHD_NO; ++ } + memcpy (&kbuf[pp->buffer_pos], + start_key, + end_key - start_key); +@@ -663,6 +667,11 @@ post_process_urlencoded (struct MHD_PostProcessor *pp, + last_escape); + pp->must_ikvi = false; + } ++ if (PP_Error == pp->state) ++ { ++ /* State in error, returning failure */ ++ return MHD_NO; ++ } + return MHD_YES; + } + +@@ -1424,7 +1433,8 @@ MHD_destroy_post_processor (struct MHD_PostProcessor *pp) + the post-processing may have been interrupted + at any stage */ + if ( (pp->xbuf_pos > 0) || +- (pp->state != PP_Done) ) ++ ( (pp->state != PP_Done) && ++ (pp->state != PP_Init) ) ) + ret = MHD_NO; + else + ret = MHD_YES; +diff --git a/src/microhttpd/test_postprocessor.c b/src/microhttpd/test_postprocessor.c +index 2c37565..cba486d 100644 +--- a/src/microhttpd/test_postprocessor.c ++++ b/src/microhttpd/test_postprocessor.c +@@ -451,6 +451,71 @@ test_empty_value (void) + } + + ++static enum MHD_Result ++value_checker2 (void *cls, ++ enum MHD_ValueKind kind, ++ const char *key, ++ const char *filename, ++ const char *content_type, ++ const char *transfer_encoding, ++ const char *data, ++ uint64_t off, ++ size_t size) ++{ ++ return MHD_YES; ++} ++ ++ ++static int ++test_overflow () ++{ ++ struct MHD_Connection connection; ++ struct MHD_HTTP_Header header; ++ struct MHD_PostProcessor *pp; ++ size_t i; ++ size_t j; ++ size_t delta; ++ char *buf; ++ ++ memset (&connection, 0, sizeof (struct MHD_Connection)); ++ memset (&header, 0, sizeof (struct MHD_HTTP_Header)); ++ connection.headers_received = &header; ++ header.header = MHD_HTTP_HEADER_CONTENT_TYPE; ++ header.value = MHD_HTTP_POST_ENCODING_FORM_URLENCODED; ++ header.header_size = strlen (header.header); ++ header.value_size = strlen (header.value); ++ header.kind = MHD_HEADER_KIND; ++ for (i = 128; i < 1024 * 1024; i += 1024) ++ { ++ pp = MHD_create_post_processor (&connection, ++ 1024, ++ &value_checker2, ++ NULL); ++ buf = malloc (i); ++ if (NULL == buf) ++ return 1; ++ memset (buf, 'A', i); ++ buf[i / 2] = '='; ++ delta = 1 + (MHD_random_ () % (i - 1)); ++ j = 0; ++ while (j < i) ++ { ++ if (j + delta > i) ++ delta = i - j; ++ if (MHD_NO == ++ MHD_post_process (pp, ++ &buf[j], ++ delta)) ++ break; ++ j += delta; ++ } ++ free (buf); ++ MHD_destroy_post_processor (pp); ++ } ++ return 0; ++} ++ ++ + int + main (int argc, char *const *argv) + { +@@ -463,6 +528,7 @@ main (int argc, char *const *argv) + errorCount += test_multipart (); + errorCount += test_nested_multipart (); + errorCount += test_empty_value (); ++ errorCount += test_overflow (); + if (errorCount != 0) + fprintf (stderr, "Error (code: %u)\n", errorCount); + return errorCount != 0; /* 0 == pass */ diff --git a/meta-oe/recipes-support/libmicrohttpd/libmicrohttpd_0.9.70.bb b/meta-oe/recipes-support/libmicrohttpd/libmicrohttpd_0.9.70.bb index 94976d2e9..9d5e85e1a 100644 --- a/meta-oe/recipes-support/libmicrohttpd/libmicrohttpd_0.9.70.bb +++ b/meta-oe/recipes-support/libmicrohttpd/libmicrohttpd_0.9.70.bb @@ -7,7 +7,8 @@ SECTION = "net" DEPENDS = "file" SRC_URI = "${GNU_MIRROR}/libmicrohttpd/${BPN}-${PV}.tar.gz \ -" + file://CVE-2021-3466.patch \ + " SRC_URI[md5sum] = "dcd6045ecb4ea18c120afedccbd1da74" SRC_URI[sha256sum] = "90d0a3d396f96f9bc41eb0f7e8187796049285fabef82604acd4879590977307"
Extract patch from the 0.9.71 release commit. Signed-off-by: Ernst Sjöstrand <ernst.sjostrand@verisure.com> --- .../libmicrohttpd/CVE-2021-3466.patch | 152 ++++++++++++++++++ .../libmicrohttpd/libmicrohttpd_0.9.70.bb | 3 +- 2 files changed, 154 insertions(+), 1 deletion(-) create mode 100644 meta-oe/recipes-support/libmicrohttpd/libmicrohttpd/CVE-2021-3466.patch -- 2.34.0