]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
fuzzers: add input size limits, always configure limits in two ways
authorYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 30 Dec 2021 19:30:43 +0000 (04:30 +0900)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Thu, 12 May 2022 11:31:11 +0000 (13:31 +0200)
Without the size limits, oss-fuzz creates huge samples that time out. Usually
this is because some of our code has bad algorithmic complexity. For data like
configuration samples we don't need to care about this: non-rogue configs are
rarely more than a few items, and a bit of a slowdown with a few hundred items
is acceptable. This wouldn't be OK for processing of untrusted data though.

We need to set the limit in two ways: through .options and in the code. The
first because it nicely allows libFuzzer to avoid wasting time, and the second
because fuzzers like hongfuzz and afl don't support .options.

While at it, let's fix an off-by-one (65535 is the largest offset for a
power-of-two size, but we're checking the size here).

Co-authored-by: Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
20 files changed:
src/core/fuzz-unit-file.c
src/fuzz/fuzz-bootspec.c
src/fuzz/fuzz-bootspec.options
src/fuzz/fuzz-env-file.c
src/fuzz/fuzz-env-file.options
src/journal-remote/fuzz-journal-remote.c
src/libsystemd/sd-bus/fuzz-bus-match.c
src/libsystemd/sd-bus/fuzz-bus-match.options [new file with mode: 0644]
src/network/fuzz-netdev-parser.c
src/network/fuzz-netdev-parser.options [new file with mode: 0644]
src/network/fuzz-network-parser.c
src/network/fuzz-network-parser.options
src/nspawn/fuzz-nspawn-oci.c
src/nspawn/fuzz-nspawn-settings.c
src/resolve/fuzz-dns-packet.options
src/udev/fuzz-udev-rules.c
src/udev/net/fuzz-link-parser.c
src/udev/net/fuzz-link-parser.options
src/xdg-autostart-generator/fuzz-xdg-desktop.c
src/xdg-autostart-generator/fuzz-xdg-desktop.options [new file with mode: 0644]

index c12e874e2dfc8a024072881b29aa92a3d96874e6..81cede2193d2ef3a97ccfe3b02684d4081e92019 100644 (file)
@@ -21,7 +21,11 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
         const char *name;
         long offset;
 
+        if (size > 65536)
+                return 0;
+
         f = data_to_file(data, size);
+
         assert_se(f);
 
         if (read_line(f, LINE_MAX, &p) < 0)
index fa9e3f06e04dac4ca284fc70fb67e34b578d7f87..0594a0dea55bf48da1e6b5f655555712c54159f2 100644 (file)
@@ -84,7 +84,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
         _cleanup_(boot_config_free) BootConfig config = BOOT_CONFIG_NULL;
         int r;
 
-        if (size > 65535)
+        if (size > 65536)
                 return 0;
 
         /* Disable most logging if not running standalone */
index 0824b19fab47140b305710cc1dad022b1ea0c02a..678d526b1ea9bd68f971f99476098759f149e2db 100644 (file)
@@ -1,2 +1,2 @@
 [libfuzzer]
-max_len = 65535
+max_len = 65536
index 3b3e6256089d9fff35e1dcef52fe4e62df45cda0..431f172306abae0494b839dfaa5b77a7cb9bef2c 100644 (file)
@@ -12,7 +12,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
         _cleanup_fclose_ FILE *f = NULL;
         _cleanup_strv_free_ char **rl = NULL, **rlp =  NULL;
 
-        if (size > 65535)
+        if (size > 65536)
                 return 0;
 
         f = data_to_file(data, size);
index 0824b19fab47140b305710cc1dad022b1ea0c02a..678d526b1ea9bd68f971f99476098759f149e2db 100644 (file)
@@ -1,2 +1,2 @@
 [libfuzzer]
-max_len = 65535
+max_len = 65536
index a8e56e21b2a36b24a63f4f7f5a242259a490668d..dd7884ee9af3cd81403b4bba2c812c044ab4ccc5 100644 (file)
@@ -24,7 +24,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
         _cleanup_(journal_remote_server_destroy) RemoteServer s = {};
         int r;
 
-        if (size <= 2)
+        if (size <= 2 || size > 65536)
                 return 0;
 
         if (!getenv("SYSTEMD_LOG_LEVEL"))
index 0585338e283c5ba1c1f79c62cc0d069b09de2467..39ab62196a45800df09b7823689fdb43eca47a5c 100644 (file)
@@ -15,6 +15,9 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
         _cleanup_(sd_bus_unrefp) sd_bus *bus = NULL;
         int r;
 
+        if (size > 65536)
+                return 0;
+
         /* We don't want to fill the logs with messages about parse errors.
          * Disable most logging if not running standalone */
         if (!getenv("SYSTEMD_LOG_LEVEL"))
diff --git a/src/libsystemd/sd-bus/fuzz-bus-match.options b/src/libsystemd/sd-bus/fuzz-bus-match.options
new file mode 100644 (file)
index 0000000..678d526
--- /dev/null
@@ -0,0 +1,2 @@
+[libfuzzer]
+max_len = 65536
index bb4b487ab21094628958529fdfd686eb78245dec..d8cbd2891c242a5d9b2fc8fa7777173ab8ea4d99 100644 (file)
@@ -11,6 +11,9 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
         _cleanup_fclose_ FILE *f = NULL;
         _cleanup_(unlink_tempfilep) char netdev_config[] = "/tmp/fuzz-networkd.XXXXXX";
 
+        if (size > 65536)
+                return 0;
+
         if (!getenv("SYSTEMD_LOG_LEVEL"))
                 log_set_max_level(LOG_CRIT);
 
diff --git a/src/network/fuzz-netdev-parser.options b/src/network/fuzz-netdev-parser.options
new file mode 100644 (file)
index 0000000..678d526
--- /dev/null
@@ -0,0 +1,2 @@
+[libfuzzer]
+max_len = 65536
index 9290aa58d6ebd3e294452b229ec8d584a93ca25c..630c86a98cef886c6737820e7774ba0791e461fc 100644 (file)
@@ -11,7 +11,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
         _cleanup_fclose_ FILE *f = NULL;
         _cleanup_(unlink_tempfilep) char network_config[] = "/tmp/fuzz-networkd.XXXXXX";
 
-        if (size > 65535)
+        if (size > 65536)
                 return 0;
 
         if (!getenv("SYSTEMD_LOG_LEVEL"))
index 0824b19fab47140b305710cc1dad022b1ea0c02a..678d526b1ea9bd68f971f99476098759f149e2db 100644 (file)
@@ -1,2 +1,2 @@
 [libfuzzer]
-max_len = 65535
+max_len = 65536
index 91f2a81dfc327d43ed2b2df287e3c471ef1af84c..7110a66187ee0d261d13e402f8d2170f8db5171e 100644 (file)
@@ -9,6 +9,9 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
         _cleanup_fclose_ FILE *f = NULL;
         _cleanup_(settings_freep) Settings *s = NULL;
 
+        if (size > 65536)
+                return 0;
+
         f = data_to_file(data, size);
         assert_se(f);
 
index 6b91e1506eb0e58f242c20d64117420c37cafff9..76838146591b025287a2a0aca297439fabcdc624 100644 (file)
@@ -9,6 +9,9 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
         _cleanup_fclose_ FILE *f = NULL;
         _cleanup_(settings_freep) Settings *s = NULL;
 
+        if (size > 65536)
+                return 0;
+
         f = data_to_file(data, size);
         assert_se(f);
 
index 0824b19fab47140b305710cc1dad022b1ea0c02a..678d526b1ea9bd68f971f99476098759f149e2db 100644 (file)
@@ -1,2 +1,2 @@
 [libfuzzer]
-max_len = 65535
+max_len = 65536
index 17f5ea121bb60952141a9137404c95d27e47a8b5..0208f8c2d8101db175ae58ec6b4e3c72b1c1aa66 100644 (file)
@@ -15,6 +15,9 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
         _cleanup_(unlink_tempfilep) char filename[] = "/tmp/fuzz-udev-rules.XXXXXX";
         int r;
 
+        if (size > 65536)
+                return 0;
+
         if (!getenv("SYSTEMD_LOG_LEVEL"))
                 log_set_max_level(LOG_CRIT);
 
index b871a4e23ca81c382789bafcd86b9994e0c44e3b..5727897305d6bd7813140d68fad070ffb8e0b325 100644 (file)
@@ -11,7 +11,7 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
         _cleanup_(unlink_tempfilep) char filename[] = "/tmp/fuzz-link-config.XXXXXX";
         _cleanup_fclose_ FILE *f = NULL;
 
-        if (size > 65535)
+        if (size > 65536)
                 return 0;
 
         if (!getenv("SYSTEMD_LOG_LEVEL"))
index 0824b19fab47140b305710cc1dad022b1ea0c02a..678d526b1ea9bd68f971f99476098759f149e2db 100644 (file)
@@ -1,2 +1,2 @@
 [libfuzzer]
-max_len = 65535
+max_len = 65536
index 52ba7ff0a47dcc4bf5db199f77c18136e1b14dd2..0ae27fc39d9f5636f450f81715c59a543a19ef09 100644 (file)
@@ -17,6 +17,9 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
         _cleanup_(xdg_autostart_service_freep) XdgAutostartService *service = NULL;
         _cleanup_(rm_rf_physical_and_freep) char *tmpdir = NULL;
 
+        if (size > 65536)
+                return 0;
+
         /* We don't want to fill the logs with messages about parse errors.
          * Disable most logging if not running standalone */
         if (!getenv("SYSTEMD_LOG_LEVEL"))
diff --git a/src/xdg-autostart-generator/fuzz-xdg-desktop.options b/src/xdg-autostart-generator/fuzz-xdg-desktop.options
new file mode 100644 (file)
index 0000000..678d526
--- /dev/null
@@ -0,0 +1,2 @@
+[libfuzzer]
+max_len = 65536