Commit Diff


commit - 0cb91010c2a52e1ff3d7d6d467a71e7117778413
commit + 187a2bf9abeb4a11e1e8a28ca012242e8776eb99
blob - 140dc7b365b0e06e287773553086811bfb255770
blob + f48caee010865e8a964ca76ea429cad5ceca65b3
--- src/box/xrow.c
+++ 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 @@ 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 - e7fc4a50f497b9523361483956a099e883985bac
blob + 81500c2d555ea82614997983c066c9c8f74b2d67
--- test/fuzz/CMakeLists.txt
+++ test/fuzz/CMakeLists.txt
@@ -93,6 +93,54 @@ 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_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_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_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 + 5d6a6e14d5145a576b0e169edb5d5e2ca08c8e7a (mode 644)
--- /dev/null
+++ test/fuzz/xrow_decode_error_fuzzer.c
@@ -0,0 +1,47 @@
+#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);
+
+	diag_destroy(diag_get());
+	assert(diag_is_empty(diag_get()) == true);
+
+	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;
+}
blob - /dev/null
blob + 32dd122c5fc94671f8cb028cd8dbee1a0b1ba2e8 (mode 644)
--- /dev/null
+++ test/fuzz/xrow_header_decode_fuzzer.c
@@ -0,0 +1,51 @@
+#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)
+{
+	const char *p = (const char *)data;
+	const char *pe = (const char *)data + size;
+	if (mp_check(&p, pe) != 0)
+		return -1;
+
+	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;
+}