Commit Diff


commit - 14a9269e7dd5371e152b9d2f65f9508945f73060
commit + f269bb52f63e39f175a233f1d9482b2f223bebed
blob - 3bfb01d5a133cdfc7f2fae8aa7787986f342fc33
blob + 32b8cf3af6cdbf6b62b51445b212374d72848ccf
--- src/box/xrow.c
+++ src/box/xrow.c
@@ -1249,7 +1249,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");
@@ -1595,7 +1596,8 @@ error:
 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. */
blob - 183b676e76ea7e3f444712e439d15bf10b9c9179
blob + 6ad7a203be7abc858a80ddf13de7df808938c234
--- test/fuzz/CMakeLists.txt
+++ test/fuzz/CMakeLists.txt
@@ -93,6 +93,46 @@ create_fuzz_test(PREFIX mp_datetime
                  LIBRARIES core fuzzer_config
 )
 
+# Building xrow library triggers building LuaJIT that doesn't support UBSan.
+# See https://github.com/tarantool/tarantool/issues/8473.
+if (NOT ENABLE_UB_SANITIZER)
+  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_decode_auth
+                   SOURCES xrow_decode_auth_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_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_watch
+                   SOURCES xrow_decode_watch_fuzzer.c
+                   LIBRARIES xrow fuzzer_config)
+endif ()
+
 include(ProtobufMutator)
 
 # UndefinedBehaviorSanitizer is not supported in LuaJIT.
blob - /dev/null
blob + 7468b3a635994d2dcf34cc38ee9f2bf21ce0ab53 (mode 644)
--- /dev/null
+++ 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;
+}
blob - /dev/null
blob + cdb597cfb2d24c2392557d24dc862f61467f77fe (mode 644)
--- /dev/null
+++ 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;
+}
blob - /dev/null
blob + 63330b4de810e59d1f6cf76b6f1ad6f09348ff4c (mode 644)
--- /dev/null
+++ 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;
+}
blob - /dev/null
blob + 4486f313702408ea2f3b11979130801d518791c5 (mode 644)
--- /dev/null
+++ 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;
+}
blob - /dev/null
blob + 087b76d239191b4776c409a472ae88c6fe3cc040 (mode 644)
--- /dev/null
+++ 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;
+}
blob - /dev/null
blob + 554abb8dbbf92ff0fed9b99dee6a95e813587c19 (mode 644)
--- /dev/null
+++ 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;
+}
blob - /dev/null
blob + 4cdc1e370433d78e7290191617481edf7cf4b998 (mode 644)
--- /dev/null
+++ 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;
+}
blob - /dev/null
blob + c76c50e8c5f10f572643341f86c853c6663b88da (mode 644)
--- /dev/null
+++ 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;
+}
blob - /dev/null
blob + 88f9b619aa28b07d8896c3070b50436bcd68d721 (mode 644)
--- /dev/null
+++ test/fuzz/xrow_greeting_decode_fuzzer.c
@@ -0,0 +1,33 @@
+#include <stdint.h>
+
+#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 == NULL)
+		return 0;
+	memcpy(greetingbuf, data, size);
+	greetingbuf[size] = '\0';
+
+	struct greeting greeting = {0};
+	greeting_decode(greetingbuf, &greeting);
+
+	free(greetingbuf);
+
+	return 0;
+}