1# Copyright (C) 2023 The Android Open Source Project 2# 3# Licensed under the Apache License, Version 2.0 (the "License"); 4# you may not use this file except in compliance with the License. 5# You may obtain a copy of the License at 6# 7# http://www.apache.org/licenses/LICENSE-2.0 8# 9# Unless required by applicable law or agreed to in writing, software 10# distributed under the License is distributed on an "AS IS" BASIS, 11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12# See the License for the specific language governing permissions and 13# limitations under the License. 14 15load("@bazel_skylib//lib:unittest.bzl", "analysistest") 16load( 17 "@soong_injection//cc_toolchain:sanitizer_constants.bzl", 18 _generated_sanitizer_constants = "constants", 19) 20load( 21 "//build/bazel/rules/cc/testing:transitions.bzl", 22 "compile_action_argv_aspect_generator", 23 "transition_deps_test_attrs", 24 "transition_deps_test_impl", 25) 26load(":cc_binary.bzl", "cc_binary") 27load(":cc_constants.bzl", "transition_constants") 28load(":cc_library_shared.bzl", "cc_library_shared") 29load(":cc_library_static.bzl", "cc_library_static") 30 31_compile_action_argv_aspect = compile_action_argv_aspect_generator({ 32 "_cc_library_combiner": ["deps", "roots", "includes"], 33 "_cc_includes": ["deps"], 34 "_cc_library_shared_proxy": ["deps"], 35 "cc_binary": ["deps"], 36 "stripped_binary": ["src", "unstripped"], 37}) 38 39_cfi_deps_test = analysistest.make( 40 transition_deps_test_impl, 41 attrs = transition_deps_test_attrs, 42 extra_target_under_test_aspects = [_compile_action_argv_aspect], 43) 44 45cfi_feature = "android_cfi" 46static_cpp_suffix = "_cpp" 47shared_or_binary_cpp_suffix = "__internal_root_cpp" 48binary_suffix = "__internal_root" 49 50def _test_cfi_propagates_to_static_deps(): 51 name = "cfi_propagates_to_static_deps" 52 static_dep_name = name + "_static_dep" 53 static_dep_of_static_dep_name = static_dep_name + "_of_static_dep" 54 test_name = name + "_test" 55 56 cc_library_shared( 57 name = name, 58 srcs = ["foo.cpp"], 59 deps = [static_dep_name], 60 features = [cfi_feature], 61 tags = ["manual"], 62 ) 63 64 cc_library_static( 65 name = static_dep_name, 66 srcs = ["bar.cpp"], 67 deps = [static_dep_of_static_dep_name], 68 tags = ["manual"], 69 ) 70 71 cc_library_static( 72 name = static_dep_of_static_dep_name, 73 srcs = ["baz.cpp"], 74 tags = ["manual"], 75 ) 76 77 _cfi_deps_test( 78 name = test_name, 79 target_under_test = name, 80 flags = [_generated_sanitizer_constants.CfiCrossDsoFlag], 81 targets_with_flag = [ 82 name + shared_or_binary_cpp_suffix, 83 static_dep_name + static_cpp_suffix, 84 static_dep_of_static_dep_name + static_cpp_suffix, 85 ], 86 targets_without_flag = [], 87 ) 88 89 return test_name 90 91def _test_cfi_does_not_propagate_to_shared_deps(): 92 name = "cfi_does_not_propagate_to_shared_deps" 93 shared_dep_name = name + "shared_dep" 94 test_name = name + "_test" 95 96 cc_library_shared( 97 name = name, 98 srcs = ["foo.cpp"], 99 deps = [shared_dep_name], 100 features = [cfi_feature], 101 tags = ["manual"], 102 ) 103 104 cc_library_shared( 105 name = shared_dep_name, 106 srcs = ["bar.cpp"], 107 tags = ["manual"], 108 ) 109 110 _cfi_deps_test( 111 name = test_name, 112 target_under_test = name, 113 flags = [_generated_sanitizer_constants.CfiCrossDsoFlag], 114 targets_with_flag = [name + shared_or_binary_cpp_suffix], 115 targets_without_flag = [shared_dep_name + shared_or_binary_cpp_suffix], 116 ) 117 118 return test_name 119 120def _test_cfi_disabled_propagates_to_static_deps(): 121 name = "cfi_disabled_propagates_to_static_deps" 122 static_dep_name = name + "_static_dep" 123 test_name = name + "_test" 124 125 cc_library_shared( 126 name = name, 127 srcs = ["foo.cpp"], 128 deps = [static_dep_name], 129 tags = ["manual"], 130 ) 131 132 cc_library_static( 133 name = static_dep_name, 134 srcs = ["bar.cpp"], 135 features = ["android_cfi"], 136 tags = ["manual"], 137 ) 138 139 _cfi_deps_test( 140 name = test_name, 141 target_under_test = name, 142 flags = [_generated_sanitizer_constants.CfiCrossDsoFlag], 143 targets_with_flag = [], 144 targets_without_flag = [ 145 name + shared_or_binary_cpp_suffix, 146 static_dep_name + static_cpp_suffix, 147 ], 148 ) 149 150 return test_name 151 152def _test_cfi_binary_propagates_to_static_deps(): 153 name = "cfi_binary_propagates_to_static_deps" 154 static_dep_name = name + "_static_dep" 155 test_name = name + "_test" 156 157 cc_binary( 158 name = name, 159 srcs = ["foo.cpp"], 160 deps = [static_dep_name], 161 features = [cfi_feature], 162 tags = ["manual"], 163 ) 164 165 cc_library_static( 166 name = static_dep_name, 167 srcs = ["bar.cpp"], 168 tags = ["manual"], 169 ) 170 171 _cfi_deps_test( 172 name = test_name, 173 target_under_test = name, 174 flags = [_generated_sanitizer_constants.CfiCrossDsoFlag], 175 targets_with_flag = [ 176 name + shared_or_binary_cpp_suffix, 177 static_dep_name + static_cpp_suffix, 178 ], 179 targets_without_flag = [], 180 ) 181 182 return test_name 183 184_cfi_deps_cfi_include_paths_test = analysistest.make( 185 transition_deps_test_impl, 186 attrs = transition_deps_test_attrs, 187 extra_target_under_test_aspects = [_compile_action_argv_aspect], 188 config_settings = { 189 transition_constants.cli_platforms_key: [ 190 "@//build/bazel/tests/products:aosp_x86_for_testing_cfi_include_path", 191 ], 192 }, 193) 194 195def _test_cfi_include_paths_enables_cfi_for_device(): 196 name = "cfi_include_paths_enables_cfi_for_device" 197 test_name = name + "_test" 198 199 cc_library_shared( 200 name = name, 201 srcs = ["foo.cpp"], 202 tags = ["manual"], 203 ) 204 205 _cfi_deps_cfi_include_paths_test( 206 name = test_name, 207 target_under_test = name, 208 flags = [_generated_sanitizer_constants.CfiCrossDsoFlag], 209 targets_with_flag = [name + shared_or_binary_cpp_suffix], 210 targets_without_flag = [], 211 ) 212 213 return test_name 214 215_cfi_deps_cfi_includes_paths_host_no_cfi_test = analysistest.make( 216 transition_deps_test_impl, 217 attrs = transition_deps_test_attrs, 218 extra_target_under_test_aspects = [_compile_action_argv_aspect], 219 config_settings = { 220 transition_constants.cli_platforms_key: [ 221 "@//build/bazel/tests/products:aosp_x86_for_testing_cfi_include_path_linux_x86", 222 ], 223 }, 224) 225 226def _test_cfi_include_paths_host_no_cfi(): 227 name = "cfi_include_paths_host_no_cfi" 228 test_name = name + "_test" 229 230 cc_library_shared( 231 name = name, 232 srcs = ["foo.cpp"], 233 tags = ["manual"], 234 ) 235 236 _cfi_deps_cfi_includes_paths_host_no_cfi_test( 237 name = test_name, 238 target_under_test = name, 239 flags = [_generated_sanitizer_constants.CfiCrossDsoFlag], 240 targets_with_flag = [], 241 targets_without_flag = [name + shared_or_binary_cpp_suffix], 242 ) 243 244 return test_name 245 246_cfi_exclude_paths_no_cfi_test = analysistest.make( 247 transition_deps_test_impl, 248 attrs = transition_deps_test_attrs, 249 extra_target_under_test_aspects = [_compile_action_argv_aspect], 250 config_settings = { 251 transition_constants.cli_platforms_key: [ 252 "@//build/bazel/tests/products:aosp_x86_for_testing_cfi_exclude_path", 253 ], 254 }, 255) 256 257def _test_cfi_exclude_paths_disable_cfi(): 258 name = "cfi_exclude_paths_disable_cfi" 259 test_name = name + "_test" 260 261 cc_library_shared( 262 name = name, 263 srcs = ["foo.cpp"], 264 features = ["android_cfi"], 265 tags = ["manual"], 266 ) 267 268 _cfi_exclude_paths_no_cfi_test( 269 name = test_name, 270 target_under_test = name, 271 flags = [_generated_sanitizer_constants.CfiCrossDsoFlag], 272 targets_with_flag = [], 273 targets_without_flag = [name + shared_or_binary_cpp_suffix], 274 ) 275 276 return test_name 277 278_enable_cfi_false_no_cfi_test = analysistest.make( 279 transition_deps_test_impl, 280 attrs = transition_deps_test_attrs, 281 extra_target_under_test_aspects = [_compile_action_argv_aspect], 282 config_settings = { 283 transition_constants.enable_cfi_key: False, 284 }, 285) 286 287def _test_enable_cfi_false_disables_cfi_globally(): 288 name = "enable_cfi_false_disables_cfi_globally" 289 test_name = name + "_test" 290 291 cc_library_shared( 292 name = name, 293 srcs = ["foo.cpp"], 294 features = ["android_cfi"], 295 tags = ["manual"], 296 ) 297 298 _enable_cfi_false_no_cfi_test( 299 name = test_name, 300 target_under_test = name, 301 flags = [_generated_sanitizer_constants.CfiCrossDsoFlag], 302 targets_with_flag = [], 303 targets_without_flag = [name + shared_or_binary_cpp_suffix], 304 ) 305 306 return test_name 307 308def cfi_transition_test_suite(name): 309 native.test_suite( 310 name = name, 311 tests = [ 312 _test_cfi_propagates_to_static_deps(), 313 _test_cfi_does_not_propagate_to_shared_deps(), 314 _test_cfi_disabled_propagates_to_static_deps(), 315 _test_cfi_binary_propagates_to_static_deps(), 316 _test_cfi_include_paths_enables_cfi_for_device(), 317 _test_cfi_include_paths_host_no_cfi(), 318 _test_cfi_exclude_paths_disable_cfi(), 319 _test_enable_cfi_false_disables_cfi_globally(), 320 ], 321 ) 322