From: Vladislav Shpilevoy <v.shpilevoy@tarantool.org> To: tarantool-patches@dev.tarantool.org, tsafin@tarantool.org, alyapunov@tarantool.org Subject: [Tarantool-patches] [PATCH 01/11] cmake: enable misc types of UB detection in clang Date: Fri, 5 Jun 2020 01:43:06 +0200 [thread overview] Message-ID: <7350df5119ea9db20957227f0595e572edbcafea.1591313754.git.v.shpilevoy@tarantool.org> (raw) In-Reply-To: <cover.1591313754.git.v.shpilevoy@tarantool.org> Option ENABLE_UB_SANITIZER enables clang undefined behaviour sanitizer. So far the only UB to detect was alignment violation. This was the biggest problem found by the sanitizer. Now when it is fixed, most of the other types of UB are also turned on to fix them as well. There is a few of exceptions - pointer type overflow, vptr check, and all types of integer overflow and truncation. Pointer type overflow detection is disabled because it is abused in the source code a lot, by stailq data structure. Vptr sanitation is a runtime check ensuring that a pointer at a non-POD type really points at an object of this type, using RTTI. The check false-positively fails in alter.cc when AlterSpaceOp class objects are stored in an rlist, and the list is iterated using rlist_foreach_entry(). In the cycle there is a condition: &item->member != head In the end the 'item' points not at an AlterSpaceOp, but at the rlist head - offsetof(typeof(item), member), at an rlist structure. Despite 'item' is never dereferenced, clang anyway generates vptr check here, which of course fails. Note, '&item->member' does not dereference item. It is item + offsetof(typeof(item), member). Just another address a few bytes after item. Integer overflow and truncation are disabled because SQL uses int64_t variables as a container of values of range [INT64_MIN, UINT64_MAX]. This works because there is a flag 'is_neg' near each such value which tells how to interpret it - as negative int64_t, or as positive uint64_t. As a result, some operations lead to a false-positive overflow. For example, consider expr_code_int() function. It essentially can do this: int64_t value; ((uint64_t *)&value) = 9223372036854775808; value = -value; 9223372036854775808 is -INT64_MIN. It can't be stored in int64_t. But the thing is that (uint64_t)9223372036854775808 is stored exactly like (int64_t)INT64_MIN, in binary form. So the expression "value = -value" looks perfectly valid: "value = -9223372036854775808", But in fact it is interpreted as "value = -(-9223372036854775808)". These integer overflow/truncation problems are going to be fixed in a separate commit due to big amount of changes needed for that. Part of #4609 --- cmake/compiler.cmake | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/cmake/compiler.cmake b/cmake/compiler.cmake index 4b23d6631..6c0fa635c 100644 --- a/cmake/compiler.cmake +++ b/cmake/compiler.cmake @@ -269,7 +269,21 @@ macro(enable_tnt_compile_flags) if (NOT CMAKE_COMPILER_IS_CLANG) message(FATAL_ERROR "Undefined behaviour sanitizer only available for clang") else() - add_compile_flags("C;CXX" "-fsanitize=alignment -fno-sanitize-recover=alignment") + set(SANITIZE_FLAGS "-fsanitize=undefined -fno-sanitize-recover=undefined") + # Stailq data structure subtracts a positive value from NULL. + set(SANITIZE_FLAGS ${SANITIZE_FLAGS} -fno-sanitize=pointer-overflow) + # Intrusive data structures may abuse '&obj->member' on pointer + # 'obj' which is not really a pointer at an object of its type. + # For example, rlist uses '&item->member' expression in macro cycles + # to check end of cycle, but on the last iteration 'item' points at + # the list metadata head, not at an object of type stored in this + # list. + set(SANITIZE_FLAGS ${SANITIZE_FLAGS} -fno-sanitize=vptr) + # Integer overflow and truncation are disabled due to extensive + # usage of this UB in SQL code to 'implement' some kind of int65_t. + set(SANITIZE_FLAGS ${SANITIZE_FLAGS} -fno-sanitize=implicit-signed-integer-truncation -fno-sanitize=implicit-integer-sign-change -fno-sanitize=signed-integer-overflow) + + add_compile_flags("C;CXX" "${SANITIZE_FLAGS}") endif() endif() -- 2.21.1 (Apple Git-122.3)
next prev parent reply other threads:[~2020-06-04 23:43 UTC|newest] Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top 2020-06-04 23:43 [Tarantool-patches] [PATCH 00/11] Enable miscelaneous sanitations Vladislav Shpilevoy 2020-06-04 23:43 ` Vladislav Shpilevoy [this message] 2020-06-04 23:43 ` [Tarantool-patches] [PATCH 10/11] sql: fix usage of not initialized index_stat Vladislav Shpilevoy 2020-06-04 23:43 ` [Tarantool-patches] [PATCH 11/11] sql: fix mem_apply_type double type truncation Vladislav Shpilevoy 2020-06-04 23:43 ` [Tarantool-patches] [PATCH 02/11] util: introduce double_compare_nint64() Vladislav Shpilevoy 2020-06-04 23:43 ` [Tarantool-patches] [PATCH 03/11] test: avoid usleep() usage for error injections Vladislav Shpilevoy 2020-06-04 23:43 ` [Tarantool-patches] [PATCH 04/11] vinyl: fix 0 division in case of canceled dump Vladislav Shpilevoy 2020-06-04 23:43 ` [Tarantool-patches] [PATCH 05/11] xrow: don't cast double to float unconditionally Vladislav Shpilevoy 2020-06-04 23:43 ` [Tarantool-patches] [PATCH 06/11] swim: fix zero division Vladislav Shpilevoy 2020-06-04 23:43 ` [Tarantool-patches] [PATCH 07/11] test: fix signed integer overflow in vclock test Vladislav Shpilevoy 2020-06-04 23:43 ` [Tarantool-patches] [PATCH 08/11] digest: eliminate UBs from guava() Vladislav Shpilevoy 2020-06-04 23:43 ` [Tarantool-patches] [PATCH 09/11] salad: fix UB pointer arithmetics in bps_tree Vladislav Shpilevoy 2020-06-05 22:09 ` [Tarantool-patches] [PATCH 00/11] Enable miscelaneous sanitations Timur Safin 2020-06-09 8:19 ` Cyrill Gorcunov 2020-06-09 8:28 ` Kirill Yukhin
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=7350df5119ea9db20957227f0595e572edbcafea.1591313754.git.v.shpilevoy@tarantool.org \ --to=v.shpilevoy@tarantool.org \ --cc=alyapunov@tarantool.org \ --cc=tarantool-patches@dev.tarantool.org \ --cc=tsafin@tarantool.org \ --subject='Re: [Tarantool-patches] [PATCH 01/11] cmake: enable misc types of UB detection in clang' \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox