From d1c8b2e807b25a15ed10016a54cb55c0f5388163 Mon Sep 17 00:00:00 2001 From: Oliver Lee Date: Tue, 26 Sep 2023 18:37:16 -0700 Subject: [PATCH] disable ubsan null checks with gcc Use of GCC with UBSan and the null, returns-nonnull-attribute, nonnull-attribute checks will cause the compiler to reject valid code due to use of the underlying GCC option -fno-delete-null-pointer-checks. This commit patches rules_cc to disable these checks if a GCC compiler is used with the ubsan feature. https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67762#c2 https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71962 This change is needed by #89. Change-Id: Ic0e5224850d8478aa92806a8f21248e979acce04 --- WORKSPACE.bazel | 30 +++++++++++ toolchain/BUILD.bazel | 15 ++++++ .../rules_cc-gcc-ubsan-no-sanitize-null.patch | 50 +++++++++++++++++++ 3 files changed, 95 insertions(+) create mode 100644 toolchain/rules_cc-gcc-ubsan-no-sanitize-null.patch diff --git a/WORKSPACE.bazel b/WORKSPACE.bazel index 290ccc3..de20e44 100644 --- a/WORKSPACE.bazel +++ b/WORKSPACE.bazel @@ -1,3 +1,5 @@ +workspace(name = "starflate") + load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") COMMON_CXX_FLAGS = ["-march=native"] @@ -35,6 +37,34 @@ host_system_libraries( load("@host_system_libraries//:defs.bzl", "HOST_SYSTEM_LIBRARIES") +# Pull in rules_cc and patch it to inject options to the `copts` attribute of +# `cc_{binary,library,test}`. This is used to disable UBSan null pointer checks +# with GCC as enabling these features will reject valid code: +# +# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67762#c2 +# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71962 +# +# Note that we cannot set these options in toolchain registration +# (bootlin_toolchain below) as the sanitize feature disable flags will precede +# `-fsanitize=undefined` from `--features=ubsan` and thus be ignored. +# +# https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html#id3 +# +# The patched cc_* rules adds the sanitize feature disable flags in `copts` only +# for GCC + UBSan builds. As these are set in `user_compile_flags`, these +# options follow `-fsanitize=undefined` when present. +# +# https://bazel.build/rules/lib/toplevel/cc_common#parameters_5 +# +http_archive( + name = "rules_cc", + patch_args = ["-p1"], + patches = ["//toolchain:rules_cc-gcc-ubsan-no-sanitize-null.patch"], + sha256 = "2037875b9a4456dce4a79d112a8ae885bbc4aad968e6587dca6e64f3a0900cdf", + strip_prefix = "rules_cc-0.0.9", + urls = ["https://github.com/bazelbuild/rules_cc/releases/download/0.0.9/rules_cc-0.0.9.tar.gz"], +) + # Note: not correct on MacOS. LLVM_COLOR_FLAGS = ["-fdiagnostics-color=always" if "libinfo.so.5" in HOST_SYSTEM_LIBRARIES else ""] diff --git a/toolchain/BUILD.bazel b/toolchain/BUILD.bazel index 6d732e3..3ee7e85 100644 --- a/toolchain/BUILD.bazel +++ b/toolchain/BUILD.bazel @@ -31,6 +31,21 @@ config_setting( constraint_values = ["@platforms//os:linux"], ) +# used to disable UBSan null pointer checks with GCC in a patched version of +# rules_cc +# +# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=67762#c2 +# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=71962 +config_setting( + name = "gcc_with_ubsan", + flag_values = { + "@bazel_tools//tools/cpp:compiler": "gcc", + }, + values = { + "features": "ubsan", + }, +) + linux_only = select({ "linux": [], "//conditions:default": ["@platforms//:incompatible"], diff --git a/toolchain/rules_cc-gcc-ubsan-no-sanitize-null.patch b/toolchain/rules_cc-gcc-ubsan-no-sanitize-null.patch new file mode 100644 index 0000000..b7c6969 --- /dev/null +++ b/toolchain/rules_cc-gcc-ubsan-no-sanitize-null.patch @@ -0,0 +1,50 @@ +diff --git a/cc/defs.bzl b/cc/defs.bzl +index a3acac7..53ee96e 100644 +--- a/cc/defs.bzl ++++ b/cc/defs.bzl +@@ -46,6 +46,18 @@ def _add_tags(attrs, is_binary = False): + + return attrs + ++def _gcc_no_sanitize_null(attrs): ++ attrs["copts"] = ( ++ attrs.get("copts", []) + ++ select({ ++ "@starflate//toolchain:gcc_with_ubsan": [ ++ "-fno-sanitize=null,returns-nonnull-attribute,nonnull-attribute", ++ ], ++ "//conditions:default": [], ++ }) ++ ) ++ return attrs ++ + def cc_binary(**attrs): + """Bazel cc_binary rule. + +@@ -56,7 +68,7 @@ def cc_binary(**attrs): + """ + + # buildifier: disable=native-cc +- native.cc_binary(**_add_tags(attrs, True)) ++ native.cc_binary(**_add_tags(_gcc_no_sanitize_null(attrs), True)) + + def cc_test(**attrs): + """Bazel cc_test rule. +@@ -68,7 +80,7 @@ def cc_test(**attrs): + """ + + # buildifier: disable=native-cc +- native.cc_test(**_add_tags(attrs, True)) ++ native.cc_test(**_add_tags(_gcc_no_sanitize_null(attrs), True)) + + def cc_library(**attrs): + """Bazel cc_library rule. +@@ -80,7 +92,7 @@ def cc_library(**attrs): + """ + + # buildifier: disable=native-cc +- native.cc_library(**_add_tags(attrs)) ++ native.cc_library(**_add_tags(_gcc_no_sanitize_null(attrs))) + + def cc_import(**attrs): + """Bazel cc_import rule.