lib/fuzzing: add fuzz_stable_sort_r_unstable
authorDouglas Bagnall <douglas.bagnall@catalyst.net.nz>
Wed, 1 May 2024 05:16:38 +0000 (17:16 +1200)
committerAndrew Bartlett <abartlet@samba.org>
Tue, 7 May 2024 23:25:35 +0000 (23:25 +0000)
This should find out how well stable_sort copes with an unstable
non-transitive comparison function.

Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
lib/fuzzing/fuzz_stable_sort_r_unstable.c [new file with mode: 0644]
lib/fuzzing/wscript_build

diff --git a/lib/fuzzing/fuzz_stable_sort_r_unstable.c b/lib/fuzzing/fuzz_stable_sort_r_unstable.c
new file mode 100644 (file)
index 0000000..cd4d791
--- /dev/null
@@ -0,0 +1,94 @@
+/*
+   Fuzzing for stable_sort
+   Copyright © Catalyst IT 2024
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "includes.h"
+#include "fuzzing/fuzzing.h"
+#include "util/stable_sort.h"
+
+
+int LLVMFuzzerInitialize(int *argc, char ***argv)
+{
+       return 0;
+}
+
+/*
+ * This function tries to never be a proper comparison function,
+ * whatever the value of ctx.
+ *
+ * If ctx is an odd number, it will change on every comparison,
+ * otherwise it will consistently use the same bad comparison
+ * technique.
+ */
+static int cmp_int8(int8_t *_a, int8_t *_b, int8_t *ctx)
+{
+       int8_t a = *_a;
+       int8_t b = *_b;
+       int8_t c = *ctx;
+
+       if (c & 1) {
+               /* aim for sustained chaos. */
+               c += a;
+               c ^= b;
+               c ^= (c >> 5) + (c << 3);
+               *ctx = (c + 99) | 1;
+       }
+       switch((c >> 1) & 7) {
+       case 0:
+               return -1;
+       case 1:
+               return 1;
+       case 2:
+               return a + b;
+       case 3:
+               return c - b;
+       case 4:
+               return (a ^ b) > c;
+       case 5:
+               return -(a > c);
+       case 6:
+               return 2 * a - b;
+       case 7:
+               break;
+       }
+       return a - c;
+}
+
+
+#define MAX_SIZE (1024 * 1024)
+
+int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t len)
+{
+       size_t i;
+       int8_t buf2[MAX_SIZE];
+       int8_t aux[MAX_SIZE];
+       int8_t context;
+
+       if (len < 3 || len > MAX_SIZE) {
+               return 0;
+       }
+       context = (int8_t)buf[0];
+       buf++;
+       len--;
+
+       memcpy(buf2, buf, len);
+
+       stable_sort_r(buf2, aux, len, 1,
+                     (samba_compare_with_context_fn_t)cmp_int8,
+                     &context);
+       return 0;
+}
index 5a9801321aacc0b20def351bac1307130b4850db..897a114ca7e91701e576f5a3bac3e12ae460937f 100644 (file)
@@ -153,6 +153,11 @@ bld.SAMBA_BINARY('fuzz_stable_sort_r',
                  deps='fuzzing stable_sort afl-fuzz-main',
                  fuzzer=True)
 
+bld.SAMBA_BINARY('fuzz_stable_sort_r_unstable',
+                 source='fuzz_stable_sort_r_unstable.c',
+                 deps='fuzzing stable_sort afl-fuzz-main',
+                 fuzzer=True)
+
 bld.SAMBA_BINARY('fuzz_security_token_vs_descriptor',
                  source='fuzz_security_token_vs_descriptor.c',
                  deps='fuzzing samba-security afl-fuzz-main',