]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
fuzz: add fuzzers for stable_sort
authorDouglas Bagnall <douglas.bagnall@catalyst.net.nz>
Wed, 30 Nov 2022 03:59:51 +0000 (16:59 +1300)
committerJoseph Sutton <jsutton@samba.org>
Thu, 1 Dec 2022 22:56:39 +0000 (22:56 +0000)
Signed-off-by: Douglas Bagnall <douglas.bagnall@catalyst.net.nz>
Reviewed-by: Joseph Sutton <josephsutton@catalyst.net.nz>
lib/fuzzing/fuzz_stable_sort.c [new file with mode: 0644]
lib/fuzzing/fuzz_stable_sort_r.c [new file with mode: 0644]
lib/fuzzing/wscript_build

diff --git a/lib/fuzzing/fuzz_stable_sort.c b/lib/fuzzing/fuzz_stable_sort.c
new file mode 100644 (file)
index 0000000..032a2a6
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+   Fuzzing for stable_sort
+   Copyright © Catalyst IT
+
+   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 "talloc.h"
+#include "util/stable_sort.h"
+
+
+int LLVMFuzzerInitialize(int *argc, char ***argv)
+{
+       return 0;
+}
+
+
+#define CMP_FN(type) static int cmp_ ## type (type *a, type *b) \
+{\
+       if (*a > *b) {\
+               return 1;\
+       }\
+       if (*a < *b) {\
+               return -1;\
+       }\
+       return 0;\
+}
+
+CMP_FN(uint8_t)
+CMP_FN(uint16_t)
+CMP_FN(uint32_t)
+CMP_FN(uint64_t)
+
+#define MAX_SIZE (1024 * 1024)
+
+int LLVMFuzzerTestOneInput(uint8_t *buf, size_t len)
+{
+       TALLOC_CTX *mem_ctx = NULL;
+       samba_compare_fn_t fn;
+       size_t s, i;
+       uint8_t buf2[MAX_SIZE];
+
+       if (len < 1 || len > MAX_SIZE) {
+               return 0;
+       }
+       s = 1 << (buf[0] & 3);
+       if (s == 1) {
+               fn = (samba_compare_fn_t)cmp_uint8_t;
+       } else if (s == 2) {
+               fn = (samba_compare_fn_t)cmp_uint16_t;
+       } else if (s == 4) {
+               fn = (samba_compare_fn_t)cmp_uint32_t;
+       } else {
+               fn = (samba_compare_fn_t)cmp_uint64_t;
+       }
+       buf++;
+       len--;
+       len -= len & (s - 1);
+
+       mem_ctx = talloc_new(NULL);
+       memcpy(buf2, buf, len);
+
+       stable_sort_talloc(mem_ctx, buf2, len / s, s, fn);
+
+       talloc_free(mem_ctx);
+
+       for (i = s; i < len; i += s) {
+               int c = fn(&buf2[i - s], &buf2[i]);
+               if (c > 0) {
+                       abort();
+               }
+       }
+
+       return 0;
+}
diff --git a/lib/fuzzing/fuzz_stable_sort_r.c b/lib/fuzzing/fuzz_stable_sort_r.c
new file mode 100644 (file)
index 0000000..0808b8f
--- /dev/null
@@ -0,0 +1,69 @@
+/*
+   Fuzzing for stable_sort
+   Copyright © Catalyst IT
+
+   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;
+}
+
+/*
+ * For a "context" we use a byte that the values are XORed with before
+ * comparison, for a non-obvious but stable sort order.
+ */
+static int cmp_int8(int8_t *a, int8_t *b, int8_t *c)
+{
+       return (*a ^ *c) - (*b ^ *c);
+}
+
+
+#define MAX_SIZE (1024 * 1024)
+
+int LLVMFuzzerTestOneInput(uint8_t *buf, size_t len)
+{
+       size_t i;
+       int8_t buf2[MAX_SIZE];
+       int8_t aux[MAX_SIZE];
+       int8_t context;
+
+       if (len < 1 || 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);
+
+       for (i = 1; i < len; i++) {
+               int c = cmp_int8(&buf2[i - 1], &buf2[i], &context);
+               if (c > 0) {
+                       abort();
+               }
+       }
+
+       return 0;
+}
index 9c559b3bcc89a3f55d96c4ebd15ce7f7316f8e77..ca6c4f777a3d662d71c3fbb5b017212b8fa49649 100644 (file)
@@ -97,6 +97,16 @@ bld.SAMBA_BINARY('fuzz_cli_credentials_parse_string',
                  deps='fuzzing samba-credentials afl-fuzz-main',
                  fuzzer=True)
 
+bld.SAMBA_BINARY('fuzz_stable_sort',
+                 source='fuzz_stable_sort.c',
+                 deps='fuzzing stable_sort afl-fuzz-main',
+                 fuzzer=True)
+
+bld.SAMBA_BINARY('fuzz_stable_sort_r',
+                 source='fuzz_stable_sort_r.c',
+                 deps='fuzzing stable_sort afl-fuzz-main',
+                 fuzzer=True)
+
 # The fuzz_type and fuzz_function parameters make the built
 # fuzzer take the same input as ndrdump and so the same that
 # could be sent to the client or server as the stub data.