• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Copyright 2022 The Chromium Authors
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5import ("//build/config/cronet/config.gni")
6import("//build/config/sanitizers/sanitizers.gni")
7import("//build_overrides/partition_alloc.gni")
8
9if (is_apple) {
10  import("//build/config/features.gni")
11}
12
13# Whether 64-bit pointers are used.
14# A static_assert in partition_alloc_config.h verifies that.
15if (is_nacl) {
16  # NaCl targets don't use 64-bit pointers.
17  has_64_bit_pointers = false
18} else if (current_cpu == "x64" || current_cpu == "arm64" ||
19           current_cpu == "loong64") {
20  has_64_bit_pointers = true
21} else if (current_cpu == "x86" || current_cpu == "arm") {
22  has_64_bit_pointers = false
23} else {
24  assert(false, "Unknown CPU: $current_cpu")
25}
26
27if (use_partition_alloc_as_malloc_default) {
28  _default_allocator = "partition"
29} else {
30  _default_allocator = "none"
31}
32
33declare_args() {
34  # Whether PartitionAlloc should be available for use or not.
35  # true makes PartitionAlloc linked to the executable or shared library and
36  # makes it available for use. It doesn't mean that the default allocator
37  # is PartitionAlloc, which is governed by |use_partition_alloc_as_malloc|.
38  #
39  # N.B. generally, embedders should look at this GN arg and at the
40  # corresponding buildflag to determine whether to interact with PA
41  # source at all (pulling the component in via GN, including headers,
42  # etc.). There is nothing stopping a lazy embedder from ignoring this
43  # and unconditionally using PA, but such a setup is inadvisable.
44  #
45  # In Chromium, this is set true, except:
46  #
47  # 1.  On Cronet bots, because Cronet doesn't use PartitionAlloc at all,
48  #     and doesn't wish to incur the library size increase (crbug.com/674570).
49  # 2.  On NaCl (through this declaration), where PartitionAlloc doesn't
50  #     build at all.
51  use_partition_alloc = !is_nacl
52}
53
54declare_args() {
55  # PartitionAlloc-Everywhere (PA-E).
56  use_partition_alloc_as_malloc =
57      use_partition_alloc && use_partition_alloc_as_malloc_default
58}
59
60declare_args() {
61  use_freeslot_bitmap = false
62
63  # Puts the regular and BRP pools right next to each other, so that we can
64  # check "belongs to one of the two pools" with a single bitmask operation.
65  glue_core_pools = false
66
67  # Introduces pointer compression support in PA.
68  #
69  # This is effective only for memory allocated from PartitionAlloc, so it is
70  # recommended to enable PA-E above, but isn't strictly necessary. Embedders
71  # can create and use PA partitions explicitly.
72  enable_pointer_compression_support = false
73
74  # Enables a bounds check when two pointers (at least one being raw_ptr) are
75  # subtracted (if supported by the underlying implementation).
76  enable_pointer_subtraction_check = false
77}
78
79declare_args() {
80  # Build support for Use-after-Free protection via BackupRefPtr (BRP),
81  # making the raw_ptr<T> implementation to RawPtrBackupRefImpl if active.
82  #
83  # These are effective only for memory allocated from PartitionAlloc, so it is
84  # recommended to enable PA-E above, but isn't strictly necessary. Embedders
85  # can create and use PA partitions explicitly.
86  #
87  # Note that |enable_backup_ref_ptr_support = true| doesn't necessarily enable
88  # BRP protection. It'll be enabled only for partition created with
89  # partition_alloc::PartitionOptions::BackupRefPtr::kEnabled.
90  enable_backup_ref_ptr_support =
91      use_partition_alloc && enable_backup_ref_ptr_support_default
92
93  # RAW_PTR_EXCLUSION macro is disabled on official builds because it increased
94  # binary size. This flag can be used to enable it for official builds too.
95  force_enable_raw_ptr_exclusion = false
96}
97
98declare_args() {
99  # Determines whether `raw_ptr_experimental<T>` is an alias for
100  # `raw_ptr<T>` or `T*` (true raw pointer).
101  #
102  # Members rewritten as `raw_ptr_experimental` rely on this as an
103  # escape hatch to degrade to a `T*` if `raw_ptr` performance proves
104  # problematic. Defaults to match standard `raw_ptr` support.
105  #
106  # One side effect of this is that `raw_ptr_experimental<T> foo_` must
107  # not use `foo_.get()`; this is incoherent when `foo_` is a `T*`.
108  # Use `base::to_address()` instead.
109  enable_raw_ptr_experimental = enable_backup_ref_ptr_support
110}
111
112assert(!enable_pointer_compression_support || glue_core_pools,
113       "Pointer compression relies on core pools being contiguous.")
114
115declare_args() {
116  # The supported platforms are supposed to match `_is_brp_supported`, but we
117  # enable the feature on Linux early because it's most widely used for security
118  # research.
119  #
120  # The implementation of ASan BRP is purpose-built to inspect Chromium
121  # internals and is entangled with `//base` s.t. it cannot be used
122  # outside of Chromium.
123  use_asan_backup_ref_ptr =
124      build_with_chromium && is_asan && (is_win || is_android || is_linux)
125
126  # Use probe-on-destruct unowned ptr detection with ASAN.
127  use_asan_unowned_ptr = false
128}
129
130# Use the version of raw_ptr<T> that allows the embedder to implement custom
131# logic.
132use_hookable_raw_ptr = use_asan_backup_ref_ptr
133
134declare_args() {
135  # - put_ref_count_in_previous_slot: place the ref-count at the end of the
136  #   previous slot (or in metadata if a slot starts on the page boundary), as
137  #   opposed to the beginning of the slot.
138  # - enable_backup_ref_ptr_slow_checks: enable additional safety checks that
139  #   are too expensive to have on by default.
140  # - enable_dangling_raw_ptr_checks: enable checking raw_ptr do not become
141  #   dangling during their lifetime.
142  # - backup_ref_ptr_poison_oob_ptr: poison out-of-bounds (OOB) pointers to
143  #   generate an exception in the event that an OOB pointer is dereferenced.
144  put_ref_count_in_previous_slot =
145      put_ref_count_in_previous_slot_default && enable_backup_ref_ptr_support
146
147  enable_backup_ref_ptr_slow_checks =
148      enable_backup_ref_ptr_slow_checks_default && enable_backup_ref_ptr_support
149
150  # Enable the feature flag required to activate backup ref pointers. That is to
151  # say `PartitionAllocBackupRefPtr`.
152  #
153  # This is meant to be used primarily on bots. It is much easier to override
154  # the feature flags using a binary flag instead of updating multiple bots's
155  # scripts to pass command line arguments.
156  enable_backup_ref_ptr_feature_flag = false
157
158  enable_dangling_raw_ptr_checks =
159      enable_dangling_raw_ptr_checks_default && enable_backup_ref_ptr_support
160
161  # Enable the feature flag required to check for dangling pointers. That is to
162  # say `PartitionAllocDanglingPtr`.
163  #
164  # This is meant to be used primarily on bots. It is much easier to override
165  # the feature flags using a binary flag instead of updating multiple bots's
166  # scripts to pass command line arguments.
167  enable_dangling_raw_ptr_feature_flag = false
168
169  # Enables the dangling raw_ptr checks feature for the performance experiment.
170  # Not every dangling pointers have been fixed or annotated yet. To avoid
171  # accounting for the cost of calling the PA's embedder's callbacks when a
172  # dangling pointer has been detected, this simulates the raw_ptr to be
173  # allowed to dangle.
174  #
175  # This flag is temporary, and isn't used by PA embedders, so it doesn't need
176  # to go through build_overrides
177  enable_dangling_raw_ptr_perf_experiment = false
178
179  # Set to `enable_backup_ref_ptr_support && has_64_bit_pointers` when enabling.
180  backup_ref_ptr_poison_oob_ptr = false
181}
182
183declare_args() {
184  # Shadow metadata is still under development and only supports Linux
185  # for now.
186  enable_shadow_metadata = false
187
188  if (is_apple) {
189    # use_blink currently assumes mach absolute ticks (eg, to ensure trace
190    # events cohere).
191    partition_alloc_enable_mach_absolute_time_ticks = is_mac || use_blink
192  }
193}
194
195# *Scan is currently only used by Chromium, and supports only 64-bit.
196use_starscan = build_with_chromium && has_64_bit_pointers
197
198pcscan_stack_supported =
199    use_starscan && (current_cpu == "x64" || current_cpu == "x86" ||
200                     current_cpu == "arm" || current_cpu == "arm64")
201
202# We want to provide assertions that guard against inconsistent build
203# args, but there is no point in having them fire if we're not building
204# PartitionAlloc at all. If `use_partition_alloc` is false, we jam all
205# related args to `false`. The prime example is NaCl, where
206# PartitionAlloc doesn't build at all.
207if (is_nacl) {
208  assert(!use_partition_alloc, "PartitionAlloc doesn't build on NaCl")
209}
210if (!use_partition_alloc) {
211  use_partition_alloc_as_malloc = false
212  enable_backup_ref_ptr_support = false
213  enable_raw_ptr_experimental = false
214  use_asan_backup_ref_ptr = false
215  use_asan_unowned_ptr = false
216  use_hookable_raw_ptr = false
217  put_ref_count_in_previous_slot = false
218  enable_backup_ref_ptr_slow_checks = false
219  enable_dangling_raw_ptr_checks = false
220  enable_dangling_raw_ptr_perf_experiment = false
221  enable_pointer_subtraction_check = false
222  backup_ref_ptr_poison_oob_ptr = false
223  use_starscan = false
224}
225
226# put_ref_count_in_previous_slot can only be used if
227# enable_backup_ref_ptr_support is true.
228assert(
229    enable_backup_ref_ptr_support || !put_ref_count_in_previous_slot,
230    "Can't put ref count in the previous slot if BackupRefPtr isn't enabled at all")
231
232# enable_backup_ref_ptr_slow_checks can only be used if enable_backup_ref_ptr_support
233# is true.
234assert(enable_backup_ref_ptr_support || !enable_backup_ref_ptr_slow_checks,
235       "Can't enable additional BackupRefPtr checks if it isn't enabled at all")
236
237assert(
238    enable_backup_ref_ptr_support || !enable_raw_ptr_experimental,
239    "Can't make `raw_ptr_experimental` = `raw_ptr` when the latter is wholly disabled")
240
241# enable_dangling_raw_ptr_checks can only be used if enable_backup_ref_ptr_support
242# is true.
243assert(
244    enable_backup_ref_ptr_support || !enable_dangling_raw_ptr_checks,
245    "Can't enable dangling raw_ptr checks if BackupRefPtr isn't enabled at all")
246
247# To run the dangling raw_ptr detector experiment, the underlying feature must
248# be enabled too.
249assert(
250    enable_dangling_raw_ptr_checks || !enable_dangling_raw_ptr_perf_experiment,
251    "Missing dangling pointer checks feature for its performance experiment")
252
253# To poison OOB pointers for BackupRefPtr, the underlying feature must
254# be enabled, too.
255assert(
256    enable_backup_ref_ptr_support || !backup_ref_ptr_poison_oob_ptr,
257    "Can't enable poisoning for OOB pointers if BackupRefPtr isn't enabled at all")
258assert(has_64_bit_pointers || !backup_ref_ptr_poison_oob_ptr,
259       "Can't enable poisoning for OOB pointers if pointers are only 32-bit")
260
261# AsanBackupRefPtr and AsanUnownedPtr are mutually exclusive variants of raw_ptr.
262assert(
263    !use_asan_unowned_ptr || !use_asan_backup_ref_ptr,
264    "Both AsanUnownedPtr and AsanBackupRefPtr can't be enabled at the same time")
265
266# BackupRefPtr and AsanBackupRefPtr are mutually exclusive variants of raw_ptr.
267assert(
268    !enable_backup_ref_ptr_support || !use_asan_backup_ref_ptr,
269    "Both BackupRefPtr and AsanBackupRefPtr can't be enabled at the same time")
270
271# BackupRefPtr and AsanUnownedPtr are mutually exclusive variants of raw_ptr.
272assert(!enable_backup_ref_ptr_support || !use_asan_unowned_ptr,
273       "Both BackupRefPtr and AsanUnownedPtr can't be enabled at the same time")
274
275# RawPtrHookableImpl and BackupRefPtr are mutually exclusive variants of raw_ptr.
276assert(
277    !use_hookable_raw_ptr || !enable_backup_ref_ptr_support,
278    "Both RawPtrHookableImpl and BackupRefPtr can't be enabled at the same time")
279
280# RawPtrHookableImpl and AsanUnownedPtr are mutually exclusive variants of raw_ptr.
281assert(
282    !use_hookable_raw_ptr || !use_asan_unowned_ptr,
283    "Both RawPtrHookableImpl and AsanUnownedPtr can't be enabled at the same time")
284
285assert(!use_asan_backup_ref_ptr || is_asan,
286       "AsanBackupRefPtr requires AddressSanitizer")
287
288assert(!use_asan_unowned_ptr || is_asan,
289       "AsanUnownedPtr requires AddressSanitizer")
290
291if (is_apple) {
292  assert(!use_blink || partition_alloc_enable_mach_absolute_time_ticks,
293         "use_blink requires partition_alloc_enable_mach_absolute_time_ticks")
294
295  assert(!is_mac || partition_alloc_enable_mach_absolute_time_ticks,
296         "mac requires partition_alloc_enable_mach_absolute_time_ticks")
297}
298
299# AsanBackupRefPtr is not supported outside Chromium. The implementation is
300# entangled with `//base`. The code is only physically located with the
301# rest of `raw_ptr` to keep it together.
302assert(build_with_chromium || !use_asan_backup_ref_ptr,
303       "AsanBackupRefPtr is not supported outside Chromium")
304
305assert(!use_asan_backup_ref_ptr || use_hookable_raw_ptr,
306       "AsanBackupRefPtr requires RawPtrHookableImpl")
307
308declare_args() {
309  enable_pkeys = is_linux && target_cpu == "x64" && !is_cronet_build
310}
311assert(!enable_pkeys || (is_linux && target_cpu == "x64"),
312       "Pkeys are only supported on x64 linux")
313