From d6135207701a2b5e26953e3c21d9ceb0401d9d98 Mon Sep 17 00:00:00 2001 From: Segwaz Date: Sat, 14 Dec 2024 16:16:44 +0000 Subject: [PATCH 1/3] libwebsockets - html and http headers parsing fuzz targets --- projects/libwebsockets/Dockerfile | 11 ++ projects/libwebsockets/build.sh | 39 ++++- projects/libwebsockets/lws_lhs_fuzzer.cpp | 87 ++++++++++ projects/libwebsockets/lws_lhs_fuzzer.dict | 160 ++++++++++++++++++ .../lws_lhs_fuzzer_seed_corpus.zip | Bin 0 -> 1721 bytes projects/libwebsockets/lws_parse_fuzzer.cpp | 109 ++++++++++++ projects/libwebsockets/lws_parse_fuzzer.dict | 119 +++++++++++++ .../lws_parse_fuzzer_seed_corpus.zip | Bin 0 -> 248 bytes .../libwebsockets/lws_parse_uri_fuzzer.cpp | 37 ++++ 9 files changed, 557 insertions(+), 5 deletions(-) create mode 100644 projects/libwebsockets/lws_lhs_fuzzer.cpp create mode 100644 projects/libwebsockets/lws_lhs_fuzzer.dict create mode 100644 projects/libwebsockets/lws_lhs_fuzzer_seed_corpus.zip create mode 100644 projects/libwebsockets/lws_parse_fuzzer.cpp create mode 100644 projects/libwebsockets/lws_parse_fuzzer.dict create mode 100644 projects/libwebsockets/lws_parse_fuzzer_seed_corpus.zip create mode 100644 projects/libwebsockets/lws_parse_uri_fuzzer.cpp diff --git a/projects/libwebsockets/Dockerfile b/projects/libwebsockets/Dockerfile index f69b308c1c37..848bf9058522 100644 --- a/projects/libwebsockets/Dockerfile +++ b/projects/libwebsockets/Dockerfile @@ -19,5 +19,16 @@ RUN apt-get update && apt-get install -y libssl-dev RUN git clone --depth 1 https://github.com/warmcat/libwebsockets.git COPY build.sh $SRC + COPY lws_upng_inflate_fuzzer.cpp $SRC/libwebsockets/ +COPY lws_lhs_fuzzer.cpp $SRC/libwebsockets/ +COPY lws_parse_uri_fuzzer.cpp $SRC/libwebsockets/ +COPY lws_parse_fuzzer.cpp $SRC/libwebsockets/ + +COPY lws_lhs_fuzzer.dict $OUT +COPY lws_parse_fuzzer.dict $OUT + +COPY lws_lhs_fuzzer_seed_corpus.zip $OUT +COPY lws_parse_fuzzer_seed_corpus.zip $OUT + WORKDIR $SRC/libwebsockets diff --git a/projects/libwebsockets/build.sh b/projects/libwebsockets/build.sh index 4dd34520c5cd..b66e3083ce3c 100755 --- a/projects/libwebsockets/build.sh +++ b/projects/libwebsockets/build.sh @@ -21,11 +21,40 @@ cd $DIR sed -i 's/-Werror//g' ./CMakeLists.txt mkdir build && cd build cmake -DCMAKE_C_FLAGS="$CFLAGS" -DCMAKE_CXX_FLAGS="$CXXFLAGS" \ - -DCMAKE_EXE_LINKER_FLAGS="$CFLAGS" -DCMAKE_SHARED_LINKER_FLAGS="$CFLAGS" .. + -DCMAKE_EXE_LINKER_FLAGS="$CFLAGS" -DCMAKE_SHARED_LINKER_FLAGS="$CFLAGS" \ + -DLWS_WITH_CUSTOM_HEADERS=ON \ + -DLWS_ROLE_WS=ON \ + .. make -j8 cd $DIR -$CXX $CFLAGS $LIB_FUZZING_ENGINE -I$DIR/build/include \ - -o $OUT/lws_upng_inflate_fuzzer lws_upng_inflate_fuzzer.cpp \ - -L$DIR/build/lib -l:libwebsockets.a \ - -L/usr/lib/x86_64-linux-gnu/ -l:libssl.so -l:libcrypto.so + +INCLUDE_DIRS="-I$DIR/build/include \ + -I$DIR/build \ + -I$DIR/lib/core/ \ + -I$DIR/lib/plat/unix -I$DIR/lib/tls/ \ + -I$DIR/lib/secure-streams/ \ + -I$DIR/lib/event-libs/ \ + -I$DIR/lib/system/smd \ + -I$DIR/lib/system/metrics/ \ + -I$DIR/lib/core-net \ + -I$DIR/lib/roles \ + -I$DIR/lib/roles/http \ + -I$DIR/lib/roles/h1 \ + -I$DIR/lib/roles/h2 \ + -I$DIR/lib/roles/ws" + +FUZZER_SRCS=( + "lws_lhs_fuzzer.cpp" + "lws_upng_inflate_fuzzer.cpp" + "lws_parse_uri_fuzzer.cpp" + "lws_parse_fuzzer.cpp" +) + +for FUZZER in "${FUZZER_SRCS[@]}"; do + FUZZER_NAME=$(basename "$FUZZER" .cpp) + $CXX $CFLAGS $LIB_FUZZING_ENGINE $INCLUDE_DIRS \ + -o "$OUT/$FUZZER_NAME" $FUZZER \ + -L"$DIR/build/lib" -l:libwebsockets.a \ + -L/usr/lib/x86_64-linux-gnu/ -l:libssl.so -l:libcrypto.so +done diff --git a/projects/libwebsockets/lws_lhs_fuzzer.cpp b/projects/libwebsockets/lws_lhs_fuzzer.cpp new file mode 100644 index 000000000000..6d157eec98bc --- /dev/null +++ b/projects/libwebsockets/lws_lhs_fuzzer.cpp @@ -0,0 +1,87 @@ +/* Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +##############################################################################*/ + +#include +#include "libwebsockets.h" + +static unsigned int m, step; + +static int +dump_atr(lws_dll2_t *d, void *user) +{ + lws_container_of(d, lhp_atr_t, list); + //lhp_atr_t *atr = lws_container_of(d, lhp_atr_t, list); + //const char *p = (const char *)&atr[1]; + + //printf("{ \"%.*s\", \"%.*s\" }, ", + // (int)atr->name_len, p, (int)atr->value_len, p + atr->name_len + 1); + + return 0; +} + +static lws_stateful_ret_t +test_cb(lhp_ctx_t *ctx, char reason) +{ + lhp_pstack_t *ps = lws_container_of(ctx->stack.tail, lhp_pstack_t, list); + if (reason == LHPCB_ELEMENT_START || reason == LHPCB_ELEMENT_END) { + lws_dll2_foreach_safe(&ps->atr, NULL, dump_atr); + lws_css_cascade_get_prop_atr(ctx, LCSP_PROP_DISPLAY); + lws_css_cascade_get_prop_atr(ctx, LCSP_PROP_COLOR); + lws_css_cascade_get_prop_atr(ctx, LCSP_PROP_FONT_SIZE); + lws_css_cascade_get_prop_atr(ctx, LCSP_PROP_FONT_FAMILY); + } + return (lws_stateful_ret_t)0; +} + +static const lws_surface_info_t ic = { + .wh_px = { { 600,0 }, { 448,0 } }, + .wh_mm = { { 114,5000000 }, { 82,5000000 } }, +}; + +static lws_displaylist_t displaylist; + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, uint32_t size) { + struct lws_context_creation_info info = {0}; + struct lws_context *cx = NULL; + lhp_ctx_t ctx; + lws_dl_rend_t drt; + size_t ssize; + const uint8_t *sdata; + + if (!size) + return (0); + memset(&ctx, 0, sizeof(ctx)); + drt.dl = &displaylist; + drt.w = ic.wh_px[0].whole; + drt.h = ic.wh_px[1].whole; + if (lws_lhp_construct(&ctx, test_cb, &drt, &ic)) + return (-1); + + lws_context_info_defaults(&info, NULL); + if (!(cx = lws_create_context(&info))) + return (0); + ctx.user1 = (uint8_t *)cx; + + ctx.flags = LHP_FLAG_DOCUMENT_END; + if (!(ctx.base_url = strdup(""))) + return (-1); + ssize = (size_t)size; + sdata = data; + lws_lhp_parse(&ctx, &sdata, &ssize); + lws_lhp_destruct(&ctx); + lws_context_destroy(cx); + return (0); +} diff --git a/projects/libwebsockets/lws_lhs_fuzzer.dict b/projects/libwebsockets/lws_lhs_fuzzer.dict new file mode 100644 index 000000000000..2805de90f990 --- /dev/null +++ b/projects/libwebsockets/lws_lhs_fuzzer.dict @@ -0,0 +1,160 @@ +# +# AFL dictionary for HTML parsers (tags only) +# ------------------------------------------- +# +# A basic collection of HTML tags likely to matter to HTML parsers. Does *not* +# include any attributes or attribute values. +# +# Created by Michal Zalewski +# + +tag_a="" +tag_abbr="" +tag_acronym="" +tag_address="
" +tag_annotation_xml="" +tag_applet="" +tag_area="" +tag_article="
" +tag_aside="