diff --git a/src/box/xrow.c b/src/box/xrow.c index 140dc7b365b0e..f48caee010865 100644 --- a/src/box/xrow.c +++ b/src/box/xrow.c @@ -1436,7 +1436,8 @@ int xrow_decode_raft(const struct xrow_header *row, struct raft_request *r, struct vclock *vclock) { - assert(row->type == IPROTO_RAFT); + if (row->type != IPROTO_RAFT) + goto bad_msgpack; if (row->bodycnt != 1 || row->group_id != GROUP_LOCAL) { diag_set(ClientError, ER_INVALID_MSGPACK, "malformed raft request"); @@ -1786,7 +1787,8 @@ xrow_decode_error(const struct xrow_header *row) int xrow_decode_begin(const struct xrow_header *row, struct begin_request *request) { - assert(row->type == IPROTO_BEGIN); + if (row->type != IPROTO_BEGIN) + goto bad_msgpack; memset(request, 0, sizeof(*request)); /** Request without extra options. */ diff --git a/test/fuzz/CMakeLists.txt b/test/fuzz/CMakeLists.txt index e7fc4a50f497b..d94f06246fed2 100644 --- a/test/fuzz/CMakeLists.txt +++ b/test/fuzz/CMakeLists.txt @@ -93,6 +93,62 @@ create_fuzz_test(PREFIX mp_datetime LIBRARIES core fuzzer_config ) +create_fuzz_test(PREFIX xrow_greeting_decode + SOURCES xrow_greeting_decode_fuzzer.c + LIBRARIES xrow fuzzer_config) + +create_fuzz_test(PREFIX xrow_decode_id + SOURCES xrow_decode_id_fuzzer.c + LIBRARIES xrow fuzzer_config) + +create_fuzz_test(PREFIX xrow_header_decode + SOURCES xrow_header_decode_fuzzer.c + LIBRARIES xrow fuzzer_config) + +create_fuzz_test(PREFIX xrow_decode_auth + SOURCES xrow_decode_auth_fuzzer.c + LIBRARIES xrow fuzzer_config) + +create_fuzz_test(PREFIX xrow_decode_ballot + SOURCES xrow_decode_ballot_fuzzer.c + LIBRARIES xrow fuzzer_config) + +create_fuzz_test(PREFIX xrow_decode_begin + SOURCES xrow_decode_begin_fuzzer.c + LIBRARIES xrow fuzzer_config) + +create_fuzz_test(PREFIX xrow_decode_call + SOURCES xrow_decode_call_fuzzer.c + LIBRARIES xrow fuzzer_config) + +create_fuzz_test(PREFIX xrow_decode_dml + SOURCES xrow_decode_dml_fuzzer.c + LIBRARIES xrow fuzzer_config) + +create_fuzz_test(PREFIX xrow_decode_error + SOURCES xrow_decode_error_fuzzer.c + LIBRARIES xrow fuzzer_config) + +create_fuzz_test(PREFIX xrow_decode_raft + SOURCES xrow_decode_raft_fuzzer.c + LIBRARIES xrow fuzzer_config) + +create_fuzz_test(PREFIX xrow_decode_sql + SOURCES xrow_decode_sql_fuzzer.c + LIBRARIES xrow fuzzer_config) + +create_fuzz_test(PREFIX xrow_decode_subscribe + SOURCES xrow_decode_subscribe_fuzzer.c + LIBRARIES xrow fuzzer_config) + +create_fuzz_test(PREFIX xrow_decode_synchro + SOURCES xrow_decode_synchro_fuzzer.c + LIBRARIES xrow fuzzer_config) + +create_fuzz_test(PREFIX xrow_decode_watch + SOURCES xrow_decode_watch_fuzzer.c + LIBRARIES xrow fuzzer_config) + include(ProtobufMutator) # UndefinedBehaviorSanitizer is not supported in LuaJIT. diff --git a/test/fuzz/xrow_decode_auth_fuzzer.c b/test/fuzz/xrow_decode_auth_fuzzer.c new file mode 100644 index 0000000000000..7468b3a635994 --- /dev/null +++ b/test/fuzz/xrow_decode_auth_fuzzer.c @@ -0,0 +1,45 @@ +#include "box/xrow.h" +#include "box/iproto_constants.h" +#include "fiber.h" +#include "memory.h" + +void +cord_on_yield(void) {} + +__attribute__((constructor)) +static void +setup(void) +{ + memory_init(); + fiber_init(fiber_c_invoke); +} + +__attribute__((destructor)) +static void +teardown(void) +{ + fiber_free(); + memory_free(); +} + +int +LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +{ + const char *d = (const char *)data; + const char *end = (const char *)data + size; + if (mp_check(&d, end) != 0) + return -1; + + struct iovec body = {0}; + body.iov_base = (void *)data; + body.iov_len = size; + struct xrow_header row = {0}; + row.body[0] = body; + row.bodycnt = 1; + row.type = IPROTO_OK; + + struct auth_request request = {0}; + xrow_decode_auth(&row, &request); + + return 0; +} diff --git a/test/fuzz/xrow_decode_begin_fuzzer.c b/test/fuzz/xrow_decode_begin_fuzzer.c new file mode 100644 index 0000000000000..cdb597cfb2d24 --- /dev/null +++ b/test/fuzz/xrow_decode_begin_fuzzer.c @@ -0,0 +1,46 @@ +#include "box/xrow.h" +#include "box/iproto_constants.h" +#include "fiber.h" +#include "memory.h" + +void +cord_on_yield(void) {} + +__attribute__((constructor)) +static void +setup(void) +{ + memory_init(); + fiber_init(fiber_c_invoke); +} + +__attribute__((destructor)) +static void +teardown(void) +{ + fiber_free(); + memory_free(); +} + +int +LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +{ + const char *d = (const char *)data; + const char *end = (const char *)data + size; + if (mp_check(&d, end) != 0) + return -1; + + struct iovec body = {0}; + body.iov_base = (void *)data; + body.iov_len = size; + struct xrow_header row = {0}; + row.body[0] = body; + row.bodycnt = 1; + row.type = IPROTO_BEGIN; + + struct begin_request request = {0}; + if (xrow_decode_begin(&row, &request) == -1) + return -1; + + return 0; +} diff --git a/test/fuzz/xrow_decode_call_fuzzer.c b/test/fuzz/xrow_decode_call_fuzzer.c new file mode 100644 index 0000000000000..63330b4de810e --- /dev/null +++ b/test/fuzz/xrow_decode_call_fuzzer.c @@ -0,0 +1,46 @@ +#include "box/xrow.h" +#include "box/iproto_constants.h" +#include "fiber.h" +#include "memory.h" + +void +cord_on_yield(void) {} + +__attribute__((constructor)) +static void +setup(void) +{ + memory_init(); + fiber_init(fiber_c_invoke); +} + +__attribute__((destructor)) +static void +teardown(void) +{ + fiber_free(); + memory_free(); +} + +int +LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +{ + const char *d = (const char *)data; + const char *end = (const char *)data + size; + if (mp_check(&d, end) != 0) + return -1; + + struct iovec body = {0}; + body.iov_base = (void *)data; + body.iov_len = size; + + struct xrow_header row = {0}; + row.type = IPROTO_CALL; /* TODO: IPROTO_CALL_16 */ + row.body[0] = body; + row.bodycnt = 1; + + struct call_request request = {0}; + xrow_decode_call(&row, &request); + + return 0; +} diff --git a/test/fuzz/xrow_decode_dml_fuzzer.c b/test/fuzz/xrow_decode_dml_fuzzer.c new file mode 100644 index 0000000000000..4486f31370240 --- /dev/null +++ b/test/fuzz/xrow_decode_dml_fuzzer.c @@ -0,0 +1,46 @@ +#include "box/xrow.h" +#include "box/iproto_constants.h" +#include "fiber.h" +#include "memory.h" + +void +cord_on_yield(void) {} + +__attribute__((constructor)) +static void +setup(void) +{ + memory_init(); + fiber_init(fiber_c_invoke); +} + +__attribute__((destructor)) +static void +teardown(void) +{ + fiber_free(); + memory_free(); +} + +int +LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +{ + const char *d = (const char *)data; + const char *end = (const char *)data + size; + if (mp_check(&d, end) != 0) + return -1; + + struct iovec body = {0}; + body.iov_base = (void *)data; + body.iov_len = size; + + struct xrow_header row = {0}; + row.body[0] = body; + row.bodycnt = 1; + + struct request request = {0}; + if (xrow_decode_dml(&row, &request, 0) == -1) + return -1; + + return 0; +} diff --git a/test/fuzz/xrow_decode_error_fuzzer.c b/test/fuzz/xrow_decode_error_fuzzer.c new file mode 100644 index 0000000000000..5039eee100e65 --- /dev/null +++ b/test/fuzz/xrow_decode_error_fuzzer.c @@ -0,0 +1,44 @@ +#include "box/xrow.h" +#include "box/iproto_constants.h" +#include "fiber.h" +#include "memory.h" + +void +cord_on_yield(void) {} + +__attribute__((constructor)) +static void +setup(void) +{ + memory_init(); + fiber_init(fiber_c_invoke); +} + +__attribute__((destructor)) +static void +teardown(void) +{ + fiber_free(); + memory_free(); +} + +int +LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +{ + const char *d = (const char *)data; + const char *end = (const char *)data + size; + if (mp_check(&d, end) != 0) + return -1; + + struct iovec body = {0}; + body.iov_base = (void *)data; + body.iov_len = size; + + struct xrow_header row = {0}; + row.body[0] = body; + row.bodycnt = 1; + + xrow_decode_error(&row); + + return 0; +} diff --git a/test/fuzz/xrow_decode_id_fuzzer.c b/test/fuzz/xrow_decode_id_fuzzer.c new file mode 100644 index 0000000000000..087b76d239191 --- /dev/null +++ b/test/fuzz/xrow_decode_id_fuzzer.c @@ -0,0 +1,46 @@ +#include "box/xrow.h" +#include "box/iproto_constants.h" +#include "fiber.h" +#include "memory.h" + +void +cord_on_yield(void) {} + +__attribute__((constructor)) +static void +setup(void) +{ + memory_init(); + fiber_init(fiber_c_invoke); +} + +__attribute__((destructor)) +static void +teardown(void) +{ + fiber_free(); + memory_free(); +} + +int +LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +{ + const char *d = (const char *)data; + const char *end = (const char *)data + size; + if (mp_check(&d, end) != 0) + return -1; + + struct iovec body = {0}; + body.iov_base = (void *)data; + body.iov_len = size; + + struct xrow_header row = {0}; + row.body[0] = body; + row.bodycnt = 1; + + struct id_request request = {0}; + if (xrow_decode_id(&row, &request) == -1) + return -1; + + return 0; +} diff --git a/test/fuzz/xrow_decode_raft_fuzzer.c b/test/fuzz/xrow_decode_raft_fuzzer.c new file mode 100644 index 0000000000000..554abb8dbbf92 --- /dev/null +++ b/test/fuzz/xrow_decode_raft_fuzzer.c @@ -0,0 +1,46 @@ +#include "box/xrow.h" +#include "box/iproto_constants.h" +#include "fiber.h" +#include "memory.h" + +void +cord_on_yield(void) {} + +__attribute__((constructor)) +static void +setup(void) +{ + memory_init(); + fiber_init(fiber_c_invoke); +} + +__attribute__((destructor)) +static void +teardown(void) +{ + fiber_free(); + memory_free(); +} + +int +LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +{ + const char *d = (const char *)data; + const char *end = (const char *)data + size; + if (mp_check(&d, end) != 0) + return -1; + + struct iovec body = {0}; + body.iov_base = (void *)data; + body.iov_len = size; + + struct xrow_header row = {0}; + row.body[0] = body; + row.bodycnt = 1; + + struct raft_request request = {0}; + struct vclock vclock = {0}; + xrow_decode_raft(&row, &request, &vclock); + + return 0; +} diff --git a/test/fuzz/xrow_decode_sql_fuzzer.c b/test/fuzz/xrow_decode_sql_fuzzer.c new file mode 100644 index 0000000000000..4cdc1e370433d --- /dev/null +++ b/test/fuzz/xrow_decode_sql_fuzzer.c @@ -0,0 +1,46 @@ +#include "box/xrow.h" +#include "box/iproto_constants.h" +#include "fiber.h" +#include "memory.h" + +void +cord_on_yield(void) {} + +__attribute__((constructor)) +static void +setup(void) +{ + memory_init(); + fiber_init(fiber_c_invoke); +} + +__attribute__((destructor)) +static void +teardown(void) +{ + fiber_free(); + memory_free(); +} + +int +LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +{ + const char *d = (const char *)data; + const char *end = (const char *)data + size; + if (mp_check(&d, end) != 0) + return -1; + + struct iovec body = {0}; + body.iov_base = (void *)data; + body.iov_len = size; + + struct xrow_header row = {0}; + row.body[0] = body; + row.bodycnt = 1; + + struct sql_request request = {0}; + if (xrow_decode_sql(&row, &request) == -1) + return -1; + + return 0; +} diff --git a/test/fuzz/xrow_decode_watch_fuzzer.c b/test/fuzz/xrow_decode_watch_fuzzer.c new file mode 100644 index 0000000000000..c76c50e8c5f10 --- /dev/null +++ b/test/fuzz/xrow_decode_watch_fuzzer.c @@ -0,0 +1,45 @@ +#include "box/xrow.h" +#include "box/iproto_constants.h" +#include "fiber.h" +#include "memory.h" + +void +cord_on_yield(void) {} + +__attribute__((constructor)) +static void +setup(void) +{ + memory_init(); + fiber_init(fiber_c_invoke); +} + +__attribute__((destructor)) +static void +teardown(void) +{ + fiber_free(); + memory_free(); +} + +int +LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +{ + const char *d = (const char *)data; + const char *end = (const char *)data + size; + if (mp_check(&d, end) != 0) + return -1; + + struct iovec body = {0}; + body.iov_base = (void *)data; + body.iov_len = size; + + struct xrow_header row = {0}; + row.body[0] = body; + row.bodycnt = 1; + + struct watch_request request = {0}; + xrow_decode_watch(&row, &request); + + return 0; +} diff --git a/test/fuzz/xrow_greeting_decode_fuzzer.c b/test/fuzz/xrow_greeting_decode_fuzzer.c new file mode 100644 index 0000000000000..0e3e06bbe06e3 --- /dev/null +++ b/test/fuzz/xrow_greeting_decode_fuzzer.c @@ -0,0 +1,34 @@ +#include + +#include "box/xrow.h" +#include "box/iproto_constants.h" +#include "trivia/util.h" + +void +cord_on_yield(void) {} + +int +LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +{ + const char *d = (const char *)data; + const char *end = (const char *)data + size; + if (mp_check(&d, end) != 0) + return -1; + + if (size < IPROTO_GREETING_SIZE + 1) + return -1; + + char *greetingbuf = xcalloc(size + 1, sizeof(char)); + if (!greetingbuf) + return 0; + memcpy(greetingbuf, data, size); + greetingbuf[size] = '\0'; + + struct greeting greeting = {0}; + if (greeting_decode(greetingbuf, &greeting) == -1) + return -1; + + free(greetingbuf); + + return 0; +} diff --git a/test/fuzz/xrow_header_decode_fuzzer.c b/test/fuzz/xrow_header_decode_fuzzer.c new file mode 100644 index 0000000000000..07244d60b03fa --- /dev/null +++ b/test/fuzz/xrow_header_decode_fuzzer.c @@ -0,0 +1,46 @@ +#include "box/iproto_constants.h" +#include "box/xrow.h" +#include "trivia/util.h" +#include "fiber.h" +#include "memory.h" + +void +cord_on_yield(void) {} + +__attribute__((constructor)) +static void +setup(void) +{ + memory_init(); + fiber_init(fiber_c_invoke); +} + +__attribute__((destructor)) +static void +teardown(void) +{ + fiber_free(); + memory_free(); +} + +int +LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +{ + char *buf = xcalloc(size, sizeof(char)); + if (buf == NULL) + return 0; + memcpy(buf, data, size); + + struct xrow_header header; + const char *pos = mp_encode_uint(buf, size); + if (!pos) + return 0; + + const char *end = pos + size; + if (xrow_header_decode(&header, &pos, end, false) == -1) + return -1; + + free(buf); + + return 0; +} diff --git a/test/unit/CMakeLists.txt b/test/unit/CMakeLists.txt index c18ef408e14a8..47281af214434 100644 --- a/test/unit/CMakeLists.txt +++ b/test/unit/CMakeLists.txt @@ -291,7 +291,7 @@ endif () create_unit_test(PREFIX mp_print_unknown_ext SOURCES mp_print_unknown_ext.c box_test_utils.c - LIBRARIES core unit box core + LIBRARIES core unit box ) create_unit_test(PREFIX guava