8d419f
From f06002981d2bd2a582d2252f7d509205bcc2a9ed Mon Sep 17 00:00:00 2001
8d419f
From: Evgeny Vereshchagin <evvers@ya.ru>
8d419f
Date: Sun, 26 Dec 2021 23:26:56 +0000
8d419f
Subject: [PATCH] tests: add fuzz-bcd
8d419f
8d419f
(cherry picked from commit 4b65fc8725fa169bf870eb022d7b346796977c21)
8d419f
8d419f
Related: #2017035
8d419f
---
8d419f
 src/boot/efi/fuzz-bcd.c  | 26 ++++++++++++++++++++++++++
8d419f
 src/boot/efi/meson.build |  3 +++
8d419f
 tools/oss-fuzz.sh        | 16 ++++++++++++++++
8d419f
 3 files changed, 45 insertions(+)
8d419f
 create mode 100644 src/boot/efi/fuzz-bcd.c
8d419f
8d419f
diff --git a/src/boot/efi/fuzz-bcd.c b/src/boot/efi/fuzz-bcd.c
8d419f
new file mode 100644
8d419f
index 0000000000..e5ed6638a4
8d419f
--- /dev/null
8d419f
+++ b/src/boot/efi/fuzz-bcd.c
8d419f
@@ -0,0 +1,26 @@
8d419f
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
8d419f
+
8d419f
+#include "alloc-util.h"
8d419f
+#include "fd-util.h"
8d419f
+#include "fuzz.h"
8d419f
+#include "utf8.h"
8d419f
+
8d419f
+#include "bcd.c"
8d419f
+
8d419f
+int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
8d419f
+        _cleanup_free_ void *p = NULL;
8d419f
+
8d419f
+        /* This limit was borrowed from src/boot/efi/boot.c */
8d419f
+        if (size > 100*1024)
8d419f
+                return 0;
8d419f
+
8d419f
+        if (!getenv("SYSTEMD_LOG_LEVEL"))
8d419f
+                log_set_max_level(LOG_CRIT);
8d419f
+
8d419f
+        p = memdup(data, size);
8d419f
+        assert_se(p);
8d419f
+
8d419f
+        char16_t *title = get_bcd_title(p, size);
8d419f
+        assert_se(!title || char16_strlen(title) >= 0);
8d419f
+        return 0;
8d419f
+}
8d419f
diff --git a/src/boot/efi/meson.build b/src/boot/efi/meson.build
8d419f
index 16b34f0ac2..229771026d 100644
8d419f
--- a/src/boot/efi/meson.build
8d419f
+++ b/src/boot/efi/meson.build
8d419f
@@ -358,6 +358,9 @@ if efi_arch[1] in ['ia32', 'x86_64', 'arm', 'aarch64']
8d419f
                  [],
8d419f
                  'HAVE_ZSTD'],
8d419f
         ]
8d419f
+        fuzzers += [
8d419f
+                [['src/boot/efi/fuzz-bcd.c']],
8d419f
+        ]
8d419f
 endif
8d419f
 
8d419f
 systemd_boot_objects = []
8d419f
diff --git a/tools/oss-fuzz.sh b/tools/oss-fuzz.sh
8d419f
index 8a19da665e..ae57fc25d5 100755
8d419f
--- a/tools/oss-fuzz.sh
8d419f
+++ b/tools/oss-fuzz.sh
8d419f
@@ -36,6 +36,13 @@ else
8d419f
     apt-get install -y gperf m4 gettext python3-pip \
8d419f
         libcap-dev libmount-dev libkmod-dev \
8d419f
         pkg-config wget python3-jinja2
8d419f
+
8d419f
+    # gnu-efi is installed here to enable -Dgnu-efi behind which fuzz-bcd
8d419f
+    # is hidden. It isn't linked against efi. It doesn't
8d419f
+    # even include "efi.h" because "bcd.c" can work in "unit test" mode
8d419f
+    # where it isn't necessary.
8d419f
+    apt-get install -y gnu-efi zstd
8d419f
+
8d419f
     pip3 install -r .github/workflows/requirements.txt --require-hashes
8d419f
 
8d419f
     # https://github.com/google/oss-fuzz/issues/6868
8d419f
@@ -56,6 +63,15 @@ fi
8d419f
 
8d419f
 ninja -v -C "$build" fuzzers
8d419f
 
8d419f
+# Compressed BCD files are kept in test/test-bcd so let's unpack them
8d419f
+# and put them all in the seed corpus.
8d419f
+bcd=$(mktemp -d)
8d419f
+for i in test/test-bcd/*.zst; do
8d419f
+     unzstd "$i" -o "$bcd/$(basename "${i%.zst}")";
8d419f
+done
8d419f
+zip -jqr "$OUT/fuzz-bcd_seed_corpus.zip" "$bcd"
8d419f
+rm -rf "$bcd"
8d419f
+
8d419f
 # The seed corpus is a separate flat archive for each fuzzer,
8d419f
 # with a fixed name ${fuzzer}_seed_corpus.zip.
8d419f
 for d in "$(dirname "$0")/../test/fuzz/fuzz-"*; do