Added rand, hash unittests
MODIFY
.gitignore
.gitignore
@@ -49,5 +49,7 @@ core\.*
test/unittests/unit_maybe_alloc
test/unittests/unit_preallocable
test/unittests/unit_list
+test/unittests/unit_rand
+test/unittests/unit_hash
examples/afl_network_proxy/afl-network-server
examples/afl_network_proxy/afl-network-client

MODIFY
GNUmakefile
GNUmakefile
@@ -403,13 +403,24 @@ document: $(COMM_HDR) include/afl-fuzz.h $(AFL_FUZZ_FILES) src/afl-common.o src/
test/unittests/unit_maybe_alloc.o : $(COMM_HDR) include/alloc-inl.h test/unittests/unit_maybe_alloc.c $(AFL_FUZZ_FILES)
@$(CC) $(CFLAGS) $(ASAN_CFLAGS) -c test/unittests/unit_maybe_alloc.c -o test/unittests/unit_maybe_alloc.o
-test/unittests/unit_preallocable.o : $(COMM_HDR) include/alloc-inl.h test/unittests/unit_preallocable.c $(AFL_FUZZ_FILES)
- @$(CC) $(CFLAGS) $(ASAN_CFLAGS) -c test/unittests/unit_preallocable.c -o test/unittests/unit_preallocable.o
-
unit_maybe_alloc: test/unittests/unit_maybe_alloc.o
@$(CC) $(CFLAGS) -Wl,--wrap=exit -Wl,--wrap=printf test/unittests/unit_maybe_alloc.o -o test/unittests/unit_maybe_alloc $(LDFLAGS) $(ASAN_LDFLAGS) -lcmocka
./test/unittests/unit_maybe_alloc
+test/unittests/unit_hash.o : $(COMM_HDR) include/alloc-inl.h test/unittests/unit_hash.c $(AFL_FUZZ_FILES) src/afl-performance.o
+ @$(CC) $(CFLAGS) $(ASAN_CFLAGS) -c test/unittests/unit_hash.c -o test/unittests/unit_hash.o
+
+unit_hash: test/unittests/unit_hash.o src/afl-performance.o
+ @$(CC) $(CFLAGS) -Wl,--wrap=exit -Wl,--wrap=printf $^ -o test/unittests/unit_hash $(LDFLAGS) $(ASAN_LDFLAGS) -lcmocka
+ ./test/unittests/unit_hash
+
+test/unittests/unit_rand.o : $(COMM_HDR) include/alloc-inl.h test/unittests/unit_rand.c $(AFL_FUZZ_FILES) src/afl-performance.o
+ @$(CC) $(CFLAGS) $(ASAN_CFLAGS) -c test/unittests/unit_rand.c -o test/unittests/unit_rand.o
+
+unit_rand: test/unittests/unit_rand.o src/afl-common.o src/afl-performance.o
+ @$(CC) $(CFLAGS) $(ASAN_CFLAGS) -Wl,--wrap=exit -Wl,--wrap=printf $^ -o test/unittests/unit_rand $(LDFLAGS) $(ASAN_LDFLAGS) -lcmocka
+ ./test/unittests/unit_rand
+
test/unittests/unit_list.o : $(COMM_HDR) include/list.h test/unittests/unit_list.c $(AFL_FUZZ_FILES)
@$(CC) $(CFLAGS) $(ASAN_CFLAGS) -c test/unittests/unit_list.c -o test/unittests/unit_list.o
@@ -417,8 +428,8 @@ unit_list: test/unittests/unit_list.o
@$(CC) $(CFLAGS) $(ASAN_CFLAGS) -Wl,--wrap=exit -Wl,--wrap=printf test/unittests/unit_list.o -o test/unittests/unit_list $(LDFLAGS) $(ASAN_LDFLAGS) -lcmocka
./test/unittests/unit_list
-test/unittests/preallocable.o : $(COMM_HDR) include/afl-prealloc.h test/unittests/preallocable.c $(AFL_FUZZ_FILES)
- @$(CC) $(CFLAGS) $(ASAN_CFLAGS) $(CFLAGS_FLTO) -c test/unittests/preallocable.c -o test/unittests/preallocable.o
+test/unittests/unit_preallocable.o : $(COMM_HDR) include/alloc-inl.h test/unittests/unit_preallocable.c $(AFL_FUZZ_FILES)
+ @$(CC) $(CFLAGS) $(ASAN_CFLAGS) -c test/unittests/unit_preallocable.c -o test/unittests/unit_preallocable.o
unit_preallocable: test/unittests/unit_preallocable.o
@$(CC) $(CFLAGS) $(ASAN_CFLAGS) -Wl,--wrap=exit -Wl,--wrap=printf test/unittests/unit_preallocable.o -o test/unittests/unit_preallocable $(LDFLAGS) $(ASAN_LDFLAGS) -lcmocka
@@ -429,7 +440,7 @@ unit_clean:
ifneq "$(shell uname)" "Darwin"
-unit: unit_maybe_alloc unit_preallocable unit_list unit_clean
+unit: unit_maybe_alloc unit_preallocable unit_list unit_clean unit_rand unit_hash
else

MODIFY
include/afl-fuzz.h
include/afl-fuzz.h
#include "sharedmem.h"
#include "forkserver.h"
#include "common.h"
+#include "hash.h"
#include <stdio.h>
#include <unistd.h>
@@ -971,13 +972,16 @@ static inline u32 rand_below(afl_state_t *afl, u32 limit) {
}
-static inline u32 get_rand_seed(afl_state_t *afl) {
+static inline s64 rand_get_seed(afl_state_t *afl) {
- if (unlikely(afl->fixed_seed)) { return (u32)afl->init_seed; }
+ if (unlikely(afl->fixed_seed)) { return afl->init_seed; }
return afl->rand_seed[0];
}
+/* initialize randomness with a given seed. Can be called again at any time. */
+void rand_set_seed(afl_state_t *afl, s64 init_seed);
+
/* Find first power of two greater or equal to val (assuming val under
2^63). */

MODIFY
src/afl-fuzz-one.c
src/afl-fuzz-one.c
@@ -2458,7 +2458,7 @@ radamsa_stage:
for (afl->stage_cur = 0; afl->stage_cur < afl->stage_max; ++afl->stage_cur) {
u32 new_len = afl->radamsa_mutate_ptr(save_buf, len, new_buf, max_len,
- get_rand_seed(afl));
+ rand_get_seed(afl));
if (new_len) {

MODIFY
src/afl-fuzz.c
src/afl-fuzz.c
@@ -289,7 +289,7 @@ int main(int argc, char **argv_orig, char **envp) {
doc_path = access(DOC_PATH, F_OK) != 0 ? (u8 *)"docs" : (u8 *)DOC_PATH;
gettimeofday(&tv, &tz);
- afl->init_seed = tv.tv_sec ^ tv.tv_usec ^ getpid();
+ rand_set_seed(afl, tv.tv_sec ^ tv.tv_usec ^ getpid());
while ((opt = getopt(argc, argv,
"+c:i:I:o:f:m:t:T:dnCB:S:M:x:QNUWe:p:s:V:E:L:hRP:")) >
@@ -311,7 +311,7 @@ int main(int argc, char **argv_orig, char **envp) {
case 's': {
- afl->init_seed = strtoul(optarg, 0L, 10);
+ rand_set_seed(afl, strtoul(optarg, 0L, 10));
afl->fixed_seed = 1;
break;
@@ -833,11 +833,6 @@ int main(int argc, char **argv_orig, char **envp) {
}
- afl->rand_seed[0] = hash64((void *)&afl->init_seed, sizeof(u32), HASH_CONST);
- afl->rand_seed[1] = afl->rand_seed[0] ^ 0x1234567890abcdef;
- afl->rand_seed[2] = afl->rand_seed[0] & 0x0123456789abcdef;
- afl->rand_seed[3] = afl->rand_seed[0] | 0x01abcde43f567908;
-
if (afl->use_radamsa) {
if (afl->limit_time_sig > 0) {

MODIFY
src/afl-performance.c
src/afl-performance.c
@@ -33,6 +33,16 @@ static inline uint64_t rotl(const uint64_t x, int k) {
}
+void rand_set_seed(afl_state_t *afl, s64 init_seed) {
+
+ afl->init_seed = init_seed;
+ afl->rand_seed[0] = hash64((void *)&afl->init_seed, sizeof(afl->init_seed), HASH_CONST);
+ afl->rand_seed[1] = afl->rand_seed[0] ^ 0x1234567890abcdef;
+ afl->rand_seed[2] = afl->rand_seed[0] & 0x0123456789abcdef;
+ afl->rand_seed[3] = afl->rand_seed[0] | 0x01abcde43f567908;
+
+}
+
uint64_t rand_next(afl_state_t *afl) {
const uint64_t result =

ADD
test/unittests/unit_hash.c
+#include <stdarg.h>
+#include <stddef.h>
+#include <setjmp.h>
+#include <assert.h>
+#include <cmocka.h>
+/* cmocka < 1.0 didn't support these features we need */
+#ifndef assert_ptr_equal
+#define assert_ptr_equal(a, b) \
+ _assert_int_equal(cast_ptr_to_largest_integral_type(a), \
+ cast_ptr_to_largest_integral_type(b), \
+ __FILE__, __LINE__)
+#define CMUnitTest UnitTest
+#define cmocka_unit_test unit_test
+#define cmocka_run_group_tests(t, setup, teardown) run_tests(t)
+#endif
+
+
+extern void mock_assert(const int result, const char* const expression,
+ const char * const file, const int line);
+#undef assert
+#define assert(expression) \
+ mock_assert((int)(expression), #expression, __FILE__, __LINE__);
+
+#include "afl-fuzz.h"
+#include "hash.h"
+
+/* remap exit -> assert, then use cmocka's mock_assert
+ (compile with `--wrap=exit`) */
+extern void exit(int status);
+extern void __real_exit(int status);
+void __wrap_exit(int status);
+void __wrap_exit(int status) {
+ assert(0);
+}
+
+/* ignore all printfs */
+#undef printf
+extern int printf(const char *format, ...);
+extern int __real_printf(const char *format, ...);
+int __wrap_printf(const char *format, ...);
+int __wrap_printf(const char *format, ...) {
+ return 1;
+}
+
+/* Rand with 0 seed would broke in the past */
+static void test_hash(void **state) {
+
+ char bitmap[64] = {0};
+ u64 hash0 = hash64(bitmap, sizeof(bitmap), 0xa5b35705);
+
+ bitmap[10] = 1;
+ u64 hash1 = hash64(bitmap, sizeof(bitmap), 0xa5b35705);
+
+ assert_int_not_equal(hash0, hash1);
+
+ bitmap[10] = 0;
+ assert_int_equal(hash0, hash64(bitmap, sizeof(bitmap), 0xa5b35705));
+
+ bitmap[10] = 1;
+ assert_int_equal(hash1, hash64(bitmap, sizeof(bitmap), 0xa5b35705));
+
+}
+
+int main(int argc, char **argv) {
+
+ const struct CMUnitTest tests[] = {
+ cmocka_unit_test(test_hash)
+ };
+
+ //return cmocka_run_group_tests (tests, setup, teardown);
+ __real_exit( cmocka_run_group_tests (tests, NULL, NULL) );
+
+ // fake return for dumb compilers
+ return 0;
+}

ADD
test/unittests/unit_rand.c
+#include <stdarg.h>
+#include <stddef.h>
+#include <setjmp.h>
+#include <assert.h>
+#include <cmocka.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+/* cmocka < 1.0 didn't support these features we need */
+#ifndef assert_ptr_equal
+#define assert_ptr_equal(a, b) \
+ _assert_int_equal(cast_ptr_to_largest_integral_type(a), \
+ cast_ptr_to_largest_integral_type(b), \
+ __FILE__, __LINE__)
+#define CMUnitTest UnitTest
+#define cmocka_unit_test unit_test
+#define cmocka_run_group_tests(t, setup, teardown) run_tests(t)
+#endif
+
+
+extern void mock_assert(const int result, const char* const expression,
+ const char * const file, const int line);
+#undef assert
+#define assert(expression) \
+ mock_assert((int)(expression), #expression, __FILE__, __LINE__);
+
+#include "afl-fuzz.h"
+
+/* remap exit -> assert, then use cmocka's mock_assert
+ (compile with `--wrap=exit`) */
+extern void exit(int status);
+extern void __real_exit(int status);
+void __wrap_exit(int status);
+void __wrap_exit(int status) {
+ assert(0);
+}
+
+/* ignore all printfs */
+#undef printf
+extern int printf(const char *format, ...);
+extern int __real_printf(const char *format, ...);
+int __wrap_printf(const char *format, ...);
+int __wrap_printf(const char *format, ...) {
+ return 1;
+}
+
+/* Rand with 0 seed would broke in the past */
+static void test_rand_0(void **state) {
+
+ afl_state_t afl = {0};
+ rand_set_seed(&afl, 0);
+
+ /* give this one chance to retry */
+ assert_int_not_equal(
+ (rand_next(&afl) != rand_next(&afl)
+ || rand_next(&afl) != rand_next(&afl))
+ , 0);
+
+}
+
+static void test_rand_below(void **state) {
+
+ afl_state_t afl = {0};
+ rand_set_seed(&afl, 1337);
+
+ afl.fsrv.dev_urandom_fd = open("/dev/urandom", O_RDONLY);
+
+ assert(!(rand_below(&afl, 9000) > 9000));
+ assert_int_equal(rand_below(&afl, 1), 0);
+
+}
+
+int main(int argc, char **argv) {
+
+ const struct CMUnitTest tests[] = {
+ cmocka_unit_test(test_rand_0),
+ cmocka_unit_test(test_rand_below)
+ };
+
+ //return cmocka_run_group_tests (tests, setup, teardown);
+ __real_exit( cmocka_run_group_tests (tests, NULL, NULL) );
+
+ // fake return for dumb compilers
+ return 0;
+}

Added rand, hash unittests