From 2f28137baa747068e14ad7bccb75c5ca83ca0c09 Mon Sep 17 00:00:00 2001
From: Sergey Bronnikov <sergeyb@tarantool.org>
Date: Wed, 16 Oct 2024 19:19:22 +0300
Subject: [PATCH] cmake: enable UBSan check signed-integer-overflow

The patch enable UBsan check signed-integer-overflow that was
disabled globally in commit 5115d9f3e0a0
("cmake: split UB sanitations into separate flags.") and disable
it for a several functions inline.

See also #10703
See also #10704
Closes #10228

NO_CHANGELOG=codehealth
NO_DOC=codehealth
NO_TEST=codehealth

(cherry picked from commit 60ba7fb4c0038d9d17387f7ce9755eb587ea1da4)
---
 cmake/compiler.cmake      |  3 ---
 src/box/sql/expr.c        |  5 +++++
 src/box/sql/func.c        |  5 +++++
 src/box/sql/util.c        | 21 +++++++++++++++++++++
 src/lib/core/datetime.c   |  6 ++++++
 src/lib/core/fiber.c      |  5 +++++
 src/trivia/config.h.cmake |  1 +
 7 files changed, 43 insertions(+), 3 deletions(-)

diff --git a/cmake/compiler.cmake b/cmake/compiler.cmake
index 12e94cfd00..9b8c317e0c 100644
--- a/cmake/compiler.cmake
+++ b/cmake/compiler.cmake
@@ -246,9 +246,6 @@ macro(enable_tnt_compile_flags)
             object-size
             # See https://github.com/tarantool/tarantool/issues/10742.
             pointer-overflow
-            # Integer overflow and truncation are disabled due to extensive
-            # usage of this UB in SQL code to 'implement' some kind of int65_t.
-            signed-integer-overflow
             # NULL checking is disabled, because this is not a UB and raises
             # lots of false-positive fails such as typeof(*obj) with
             # obj == NULL, or memcpy() with NULL argument and 0 size.
diff --git a/src/box/sql/expr.c b/src/box/sql/expr.c
index 95844b76c7..b5aa42ff1e 100644
--- a/src/box/sql/expr.c
+++ b/src/box/sql/expr.c
@@ -3166,6 +3166,11 @@ expr_code_dec(struct Parse *parser, struct Expr *expr, bool is_neg, int reg)
  * @param neg_flag True if value is negative.
  * @param mem Register to store parsed integer
  */
+#if ENABLE_UB_SANITIZER
+static void
+expr_code_int(struct Parse *parse, struct Expr *expr, bool is_neg, int mem)
+__attribute__((no_sanitize("signed-integer-overflow")));
+#endif
 static void
 expr_code_int(struct Parse *parse, struct Expr *expr, bool is_neg,
 	      int mem)
diff --git a/src/box/sql/func.c b/src/box/sql/func.c
index 3aa29f419f..8df4338400 100644
--- a/src/box/sql/func.c
+++ b/src/box/sql/func.c
@@ -234,6 +234,11 @@ step_group_concat(struct sql_context *ctx, int argc, const struct Mem *argv)
 }
 
 /** Implementations of the ABS() function. */
+#if ENABLE_UB_SANITIZER
+static void
+func_abs_int(struct sql_context *ctx, int argc, const struct Mem *argv)
+  __attribute__((no_sanitize("signed-integer-overflow")));
+#endif
 static void
 func_abs_int(struct sql_context *ctx, int argc, const struct Mem *argv)
 {
diff --git a/src/box/sql/util.c b/src/box/sql/util.c
index 7e6826976a..3dfb28a087 100644
--- a/src/box/sql/util.c
+++ b/src/box/sql/util.c
@@ -820,6 +820,13 @@ sqlHexToBlob(const char *z, int n)
 	return zBlob;
 }
 
+#if ENABLE_UB_SANITIZER
+/* See https://github.com/tarantool/tarantool/issues/10703. */
+int
+sql_add_int(int64_t lhs, bool is_lhs_neg, int64_t rhs, bool is_rhs_neg,
+	    int64_t *res, bool *is_res_neg)
+  __attribute__((no_sanitize("signed-integer-overflow")));
+#endif
 int
 sql_add_int(int64_t lhs, bool is_lhs_neg, int64_t rhs, bool is_rhs_neg,
 	    int64_t *res, bool *is_res_neg)
@@ -849,6 +856,13 @@ sql_add_int(int64_t lhs, bool is_lhs_neg, int64_t rhs, bool is_rhs_neg,
 	return 0;
 }
 
+#if ENABLE_UB_SANITIZER
+/* See https://github.com/tarantool/tarantool/issues/10703. */
+int
+sql_sub_int(int64_t lhs, bool is_lhs_neg, int64_t rhs, bool is_rhs_neg,
+	    int64_t *res, bool *is_res_neg)
+  __attribute__((no_sanitize("signed-integer-overflow")));
+#endif
 int
 sql_sub_int(int64_t lhs, bool is_lhs_neg, int64_t rhs, bool is_rhs_neg,
 	    int64_t *res, bool *is_res_neg)
@@ -934,6 +948,13 @@ sql_mul_int(int64_t lhs, bool is_lhs_neg, int64_t rhs, bool is_rhs_neg,
 	return 0;
 }
 
+#if ENABLE_UB_SANITIZER
+/* See https://github.com/tarantool/tarantool/issues/10703. */
+int
+sql_div_int(int64_t lhs, bool is_lhs_neg, int64_t rhs, bool is_rhs_neg,
+	    int64_t *res, bool *is_res_neg)
+  __attribute__((no_sanitize("signed-integer-overflow")));
+#endif
 int
 sql_div_int(int64_t lhs, bool is_lhs_neg, int64_t rhs, bool is_rhs_neg,
 	    int64_t *res, bool *is_res_neg)
diff --git a/src/lib/core/datetime.c b/src/lib/core/datetime.c
index 22b7705910..6ee0b752ee 100644
--- a/src/lib/core/datetime.c
+++ b/src/lib/core/datetime.c
@@ -34,6 +34,12 @@
  * since Rata Die (0001-01-01).
  * DT_EPOCH_1970_OFFSET is the distance in days from Rata Die to Epoch.
  */
+#if ENABLE_UB_SANITIZER
+/* See https://github.com/tarantool/tarantool/issues/10704. */
+static int
+local_dt(int64_t secs)
+  __attribute__((no_sanitize("signed-integer-overflow")));
+#endif
 static int
 local_dt(int64_t secs)
 {
diff --git a/src/lib/core/fiber.c b/src/lib/core/fiber.c
index b5782d9784..445525b5be 100644
--- a/src/lib/core/fiber.c
+++ b/src/lib/core/fiber.c
@@ -276,6 +276,11 @@ static __thread bool fiber_parent_backtrace_enabled;
  * An action performed each time a context switch happens.
  * Used to count each fiber's processing time.
  */
+#if ENABLE_UB_SANITIZER
+static inline void
+clock_set_on_csw(struct fiber *caller)
+  __attribute__((no_sanitize("signed-integer-overflow")));
+#endif
 static inline void
 clock_set_on_csw(struct fiber *caller)
 {
diff --git a/src/trivia/config.h.cmake b/src/trivia/config.h.cmake
index dfdb9129d6..f3ddd3cc30 100644
--- a/src/trivia/config.h.cmake
+++ b/src/trivia/config.h.cmake
@@ -273,6 +273,7 @@
 #define DEFAULT_CFG SYSCONF_DIR "/" DEFAULT_CFG_FILENAME
 
 #cmakedefine ENABLE_ASAN 1
+#cmakedefine ENABLE_UB_SANITIZER 1
 
 /* Cacheline size to calculate alignments */
 #define CACHELINE_SIZE 64
-- 
GitLab