From b2a9219a04832f27aafb3a4befb00bbb3affd5be Mon Sep 17 00:00:00 2001 From: sunilnom Date: Fri, 22 May 2026 18:17:30 +0530 Subject: [PATCH 01/10] ci: add Dependabot configuration for GitHub Actions updates --- .github/dependabot.yml | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 .github/dependabot.yml diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000..70deb75 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,15 @@ +# +# BSD 3-Clause License +# Copyright (C) 2026 Intel Corporation +# SPDX-License-Identifier: BSD-3-Clause +# +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "weekly" + day: "monday" + open-pull-requests-limit: 10 + labels: + - "dependencies" From 37c53292ec09b05e216fc2ac9331d2a47d0a1a8e Mon Sep 17 00:00:00 2001 From: sunilnom Date: Fri, 22 May 2026 18:25:41 +0530 Subject: [PATCH 02/10] feat: add AFL fuzzing harness and CI workflow for config parser --- .github/workflows/fuzz.yml | 81 ++++++++++++++++++++++++++++++++++ fuzz/corpus/empty_object.json | 1 + fuzz/corpus/malformed.json | 1 + fuzz/corpus/multi_session.json | 1 + fuzz/corpus/valid_config.json | 24 ++++++++++ fuzz/fuzz_config_reader.c | 56 +++++++++++++++++++++++ 6 files changed, 164 insertions(+) create mode 100644 .github/workflows/fuzz.yml create mode 100644 fuzz/corpus/empty_object.json create mode 100644 fuzz/corpus/malformed.json create mode 100644 fuzz/corpus/multi_session.json create mode 100644 fuzz/corpus/valid_config.json create mode 100644 fuzz/fuzz_config_reader.c diff --git a/.github/workflows/fuzz.yml b/.github/workflows/fuzz.yml new file mode 100644 index 0000000..cf23f1c --- /dev/null +++ b/.github/workflows/fuzz.yml @@ -0,0 +1,81 @@ +# +# BSD 3-Clause License +# Copyright (C) 2026 Intel Corporation +# SPDX-License-Identifier: BSD-3-Clause +# +name: Fuzz Testing (AFL) + +on: + push: + branches: + - main + pull_request: + branches: + - main + schedule: + # Weekly on Wednesday at 04:00 UTC + - cron: '0 4 * * 3' + workflow_dispatch: + +permissions: {} + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + fuzz: + name: AFL Fuzz - Config Parser + runs-on: ubuntu-latest + permissions: + contents: read + + steps: + - name: Checkout repository + uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + persist-credentials: false + + - name: Install dependencies + run: | + sudo apt-get update + sudo apt-get install -y afl++ libavutil-dev libavformat-dev libavcodec-dev libswscale-dev pkg-config + + - name: Build fuzz harness + run: | + cd fuzz + AFL_CC=afl-clang-fast afl-clang-fast -o fuzz_config_reader \ + fuzz_config_reader.c \ + ../src/util/config_reader.c \ + ../src/util/logger.c \ + -I../include \ + $(pkg-config --cflags --libs libavutil) \ + -lm -g -O1 -fno-omit-frame-pointer \ + -fsanitize=address,undefined + + - name: Run AFL fuzzer (timed) + run: | + cd fuzz + mkdir -p findings + # Run AFL for 5 minutes (CI time-boxed) + timeout 300 afl-fuzz -i corpus/ -o findings/ -V 300 -- ./fuzz_config_reader @@ || true + + - name: Check for crashes + run: | + cd fuzz + CRASH_COUNT=$(find findings/default/crashes -type f ! -name "README.txt" 2>/dev/null | wc -l) + echo "Crashes found: $CRASH_COUNT" + if [ "$CRASH_COUNT" -gt 0 ]; then + echo "::error::AFL found $CRASH_COUNT crash(es)!" + ls -la findings/default/crashes/ + exit 1 + fi + echo "No crashes found — fuzzing passed." + + - name: Upload fuzzing results + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 + if: always() + with: + name: afl-fuzz-results-${{ github.run_id }} + path: fuzz/findings/ + retention-days: 14 diff --git a/fuzz/corpus/empty_object.json b/fuzz/corpus/empty_object.json new file mode 100644 index 0000000..0967ef4 --- /dev/null +++ b/fuzz/corpus/empty_object.json @@ -0,0 +1 @@ +{} diff --git a/fuzz/corpus/malformed.json b/fuzz/corpus/malformed.json new file mode 100644 index 0000000..8b13789 --- /dev/null +++ b/fuzz/corpus/malformed.json @@ -0,0 +1 @@ + diff --git a/fuzz/corpus/multi_session.json b/fuzz/corpus/multi_session.json new file mode 100644 index 0000000..20c9bdb --- /dev/null +++ b/fuzz/corpus/multi_session.json @@ -0,0 +1 @@ +{"tx_sessions": [{"udp_port": 20000, "payload_type": 96, "crop": {"x": 0, "y": 0, "w": 640, "h": 1080}}, {"udp_port": 20002, "payload_type": 96, "crop": {"x": 640, "y": 0, "w": 640, "h": 1080}}, {"udp_port": 20004, "payload_type": 96, "crop": {"x": 1280, "y": 0, "w": 640, "h": 1080}}], "interfaces": [{"name": "0000:06:00.0", "sip": "192.168.50.29", "dip": "239.168.85.20"}], "video": {"width": 1920, "height": 1080, "fps": 60, "fmt": "yuv420", "tx_url": "/dev/null"}} diff --git a/fuzz/corpus/valid_config.json b/fuzz/corpus/valid_config.json new file mode 100644 index 0000000..6bddc6f --- /dev/null +++ b/fuzz/corpus/valid_config.json @@ -0,0 +1,24 @@ +{ + "log_file": "dvledtx.log", + "interfaces": [ + { + "name": "0000:06:00.0", + "sip": "192.168.50.29", + "dip": "239.168.85.20" + } + ], + "video": { + "width": 1920, + "height": 1080, + "fps": 30, + "fmt": "yuv422p10le", + "tx_url": "/dev/null" + }, + "tx_sessions": [ + { + "udp_port": 20000, + "payload_type": 96, + "crop": { "x": 0, "y": 0, "w": 1920, "h": 1080 } + } + ] +} diff --git a/fuzz/fuzz_config_reader.c b/fuzz/fuzz_config_reader.c new file mode 100644 index 0000000..30f1e2e --- /dev/null +++ b/fuzz/fuzz_config_reader.c @@ -0,0 +1,56 @@ +/* SPDX-License-Identifier: BSD-3-Clause + * Copyright 2026 Intel Corporation + * + * AFL fuzzing harness for the JSON config parser. + * Build: afl-gcc -o fuzz_config_reader fuzz_config_reader.c ../src/util/config_reader.c + * ../src/util/logger.c -I../include $(pkg-config --cflags --libs libavutil) -lm + * Run: afl-fuzz -i corpus/ -o findings/ -- ./fuzz_config_reader @@ + */ + +#include +#include +#include +#include "util/config_reader.h" + +#ifdef __AFL_HAVE_MANUAL_CONTROL +__AFL_FUZZ_INIT(); +#endif + +int main(int argc, char *argv[]) { +#ifdef __AFL_HAVE_MANUAL_CONTROL + __AFL_INIT(); + unsigned char *buf = __AFL_FUZZ_TESTCASE_BUF; + + while (__AFL_LOOP(10000)) { + int len = __AFL_FUZZ_TESTCASE_LEN; + if (len < 2) continue; + + /* Write fuzz input to a temporary file for parse_tx_config */ + char tmpfile[] = "/tmp/fuzz_cfg_XXXXXX"; + int fd = mkstemp(tmpfile); + if (fd < 0) continue; + write(fd, buf, len); + close(fd); + + struct dvledtx_config config; + memset(&config, 0, sizeof(config)); + parse_tx_config(tmpfile, &config); + validate_tx_config(&config); + + unlink(tmpfile); + } +#else + /* Standard mode: read from file argument */ + if (argc != 2) { + fprintf(stderr, "Usage: %s \n", argv[0]); + return 1; + } + + struct dvledtx_config config; + memset(&config, 0, sizeof(config)); + parse_tx_config(argv[1], &config); + validate_tx_config(&config); +#endif + + return 0; +} From ddef34fa56e296f38d43a81686b43759e164f814 Mon Sep 17 00:00:00 2001 From: sunilnom Date: Fri, 22 May 2026 18:33:14 +0530 Subject: [PATCH 03/10] fix: add cooldown configuration to Dependabot schedule --- .github/dependabot.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 70deb75..a071668 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -10,6 +10,9 @@ updates: schedule: interval: "weekly" day: "monday" + cooldown: + default-days: 3 + semver-major-days: 7 open-pull-requests-limit: 10 labels: - "dependencies" From 45f4b238b2be4150817cc69cb28cbf35a25c3e5b Mon Sep 17 00:00:00 2001 From: sunilnom Date: Fri, 22 May 2026 18:36:22 +0530 Subject: [PATCH 04/10] fix: split AFL build into compile+link to avoid MAX_PARAMS_NUM limit --- .github/workflows/fuzz.yml | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/.github/workflows/fuzz.yml b/.github/workflows/fuzz.yml index cf23f1c..9243454 100644 --- a/.github/workflows/fuzz.yml +++ b/.github/workflows/fuzz.yml @@ -44,14 +44,16 @@ jobs: - name: Build fuzz harness run: | cd fuzz - AFL_CC=afl-clang-fast afl-clang-fast -o fuzz_config_reader \ - fuzz_config_reader.c \ - ../src/util/config_reader.c \ - ../src/util/logger.c \ - -I../include \ - $(pkg-config --cflags --libs libavutil) \ - -lm -g -O1 -fno-omit-frame-pointer \ - -fsanitize=address,undefined + export CC=afl-clang-fast + export AFL_CC=afl-clang-fast + CFLAGS="-g -O1 -fno-omit-frame-pointer -fsanitize=address,undefined -I../include $(pkg-config --cflags libavutil)" + LDFLAGS="$(pkg-config --libs libavutil) -lm -fsanitize=address,undefined" + # Compile objects separately to avoid too many params + $CC $CFLAGS -c fuzz_config_reader.c -o fuzz_config_reader.o + $CC $CFLAGS -c ../src/util/config_reader.c -o config_reader.o + $CC $CFLAGS -c ../src/util/logger.c -o logger.o + # Link + $CC -o fuzz_config_reader fuzz_config_reader.o config_reader.o logger.o $LDFLAGS - name: Run AFL fuzzer (timed) run: | From a34a6032c1c710c90b6740533dbc9808c7229041 Mon Sep 17 00:00:00 2001 From: sunilnom Date: Fri, 22 May 2026 18:40:23 +0530 Subject: [PATCH 05/10] fix: use minimal compile flags and gcc linker to avoid AFL param limit --- .github/workflows/fuzz.yml | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/.github/workflows/fuzz.yml b/.github/workflows/fuzz.yml index 9243454..118ea8f 100644 --- a/.github/workflows/fuzz.yml +++ b/.github/workflows/fuzz.yml @@ -45,15 +45,12 @@ jobs: run: | cd fuzz export CC=afl-clang-fast - export AFL_CC=afl-clang-fast - CFLAGS="-g -O1 -fno-omit-frame-pointer -fsanitize=address,undefined -I../include $(pkg-config --cflags libavutil)" - LDFLAGS="$(pkg-config --libs libavutil) -lm -fsanitize=address,undefined" - # Compile objects separately to avoid too many params - $CC $CFLAGS -c fuzz_config_reader.c -o fuzz_config_reader.o - $CC $CFLAGS -c ../src/util/config_reader.c -o config_reader.o - $CC $CFLAGS -c ../src/util/logger.c -o logger.o - # Link - $CC -o fuzz_config_reader fuzz_config_reader.o config_reader.o logger.o $LDFLAGS + # Compile each file separately with minimal flags to avoid AFL MAX_PARAMS_NUM + $CC -g -O1 -fno-omit-frame-pointer -I../include -c fuzz_config_reader.c -o fuzz_config_reader.o + $CC -g -O1 -fno-omit-frame-pointer -I../include -c ../src/util/config_reader.c -o config_reader.o + $CC -g -O1 -fno-omit-frame-pointer -I../include -c ../src/util/logger.c -o logger.o + # Link with gcc to avoid AFL param limit on linker flags + gcc -o fuzz_config_reader fuzz_config_reader.o config_reader.o logger.o -lavutil -lm - name: Run AFL fuzzer (timed) run: | From fab0f6fbfa4a610cd93d0264247293b58fbdcc48 Mon Sep 17 00:00:00 2001 From: sunilnom Date: Fri, 22 May 2026 18:43:45 +0530 Subject: [PATCH 06/10] fix: move cooldown to update-entry level per zizmor requirement --- .github/dependabot.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/.github/dependabot.yml b/.github/dependabot.yml index a071668..fc1e191 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -10,9 +10,8 @@ updates: schedule: interval: "weekly" day: "monday" - cooldown: - default-days: 3 - semver-major-days: 7 open-pull-requests-limit: 10 labels: - "dependencies" + cooldown: + default-days: 7 From 3059b20b4f1e2f3d61931c78317fc259a783b784 Mon Sep 17 00:00:00 2001 From: sunilnom Date: Fri, 22 May 2026 18:46:02 +0530 Subject: [PATCH 07/10] fix: add missing unistd.h include in fuzz harness --- fuzz/fuzz_config_reader.c | 1 + 1 file changed, 1 insertion(+) diff --git a/fuzz/fuzz_config_reader.c b/fuzz/fuzz_config_reader.c index 30f1e2e..880e594 100644 --- a/fuzz/fuzz_config_reader.c +++ b/fuzz/fuzz_config_reader.c @@ -10,6 +10,7 @@ #include #include #include +#include #include "util/config_reader.h" #ifdef __AFL_HAVE_MANUAL_CONTROL From 774e852c61f60356712a6e7d00fd6d949be99191 Mon Sep 17 00:00:00 2001 From: sunilnom Date: Fri, 22 May 2026 18:48:20 +0530 Subject: [PATCH 08/10] fix: use afl-clang-fast for linking to resolve AFL runtime symbols --- .github/workflows/fuzz.yml | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/.github/workflows/fuzz.yml b/.github/workflows/fuzz.yml index 118ea8f..350d752 100644 --- a/.github/workflows/fuzz.yml +++ b/.github/workflows/fuzz.yml @@ -41,6 +41,21 @@ jobs: sudo apt-get update sudo apt-get install -y afl++ libavutil-dev libavformat-dev libavcodec-dev libswscale-dev pkg-config + - name: Verify environment + run: | + echo "=== AFL++ ===" + afl-clang-fast --version || { echo "ERROR: afl-clang-fast not found"; exit 1; } + echo "" + echo "=== libavutil ===" + dpkg -l libavutil-dev | grep -q ii || { echo "ERROR: libavutil-dev not installed"; exit 1; } + echo " Header: $(find /usr/include -name 'avutil.h' | head -1)" + echo " Library: $(find /usr/lib -name 'libavutil.so*' | head -1)" + echo "" + echo "=== Compiler ===" + gcc --version | head -1 + echo "" + echo "Environment OK" + - name: Build fuzz harness run: | cd fuzz @@ -49,8 +64,9 @@ jobs: $CC -g -O1 -fno-omit-frame-pointer -I../include -c fuzz_config_reader.c -o fuzz_config_reader.o $CC -g -O1 -fno-omit-frame-pointer -I../include -c ../src/util/config_reader.c -o config_reader.o $CC -g -O1 -fno-omit-frame-pointer -I../include -c ../src/util/logger.c -o logger.o - # Link with gcc to avoid AFL param limit on linker flags - gcc -o fuzz_config_reader fuzz_config_reader.o config_reader.o logger.o -lavutil -lm + # Link with afl-clang-fast (needs AFL runtime), pass only linker libs directly + $CC -o fuzz_config_reader fuzz_config_reader.o config_reader.o logger.o -lavutil -lm + echo "Build successful: $(file fuzz_config_reader)" - name: Run AFL fuzzer (timed) run: | From cb85fda6e0d732375f61c568c14c27aeca311ea5 Mon Sep 17 00:00:00 2001 From: sunilnom Date: Fri, 22 May 2026 18:51:05 +0530 Subject: [PATCH 09/10] fix: set AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES for CI core_pattern --- .github/workflows/fuzz.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/fuzz.yml b/.github/workflows/fuzz.yml index 350d752..68caa73 100644 --- a/.github/workflows/fuzz.yml +++ b/.github/workflows/fuzz.yml @@ -72,6 +72,8 @@ jobs: run: | cd fuzz mkdir -p findings + export AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES=1 + export AFL_SKIP_CPUFREQ=1 # Run AFL for 5 minutes (CI time-boxed) timeout 300 afl-fuzz -i corpus/ -o findings/ -V 300 -- ./fuzz_config_reader @@ || true From d7502e3ae90a596d81ee7cb06117a13cc9979b94 Mon Sep 17 00:00:00 2001 From: sunilnom Date: Fri, 22 May 2026 18:58:14 +0530 Subject: [PATCH 10/10] fix: sanitize AFL filenames (replace colons) before artifact upload --- .github/workflows/fuzz.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/fuzz.yml b/.github/workflows/fuzz.yml index 68caa73..93c6b30 100644 --- a/.github/workflows/fuzz.yml +++ b/.github/workflows/fuzz.yml @@ -89,6 +89,15 @@ jobs: fi echo "No crashes found — fuzzing passed." + - name: Sanitize AFL filenames for upload + if: always() + run: | + cd fuzz/findings + # Rename files with colons (AFL naming) to use underscores + find . -name '*:*' | while read f; do + mv "$f" "$(echo "$f" | tr ':' '_')" + done + - name: Upload fuzzing results uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 if: always()