# Copyright 2022 The Chromium Authors # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. import ("//build/config/cronet/config.gni") import("//build/config/sanitizers/sanitizers.gni") import("//build_overrides/partition_alloc.gni") if (is_apple) { import("//build/config/features.gni") } # Whether 64-bit pointers are used. # A static_assert in partition_alloc_config.h verifies that. if (is_nacl) { # NaCl targets don't use 64-bit pointers. has_64_bit_pointers = false } else if (current_cpu == "x64" || current_cpu == "arm64" || current_cpu == "loong64") { has_64_bit_pointers = true } else if (current_cpu == "x86" || current_cpu == "arm") { has_64_bit_pointers = false } else { assert(false, "Unknown CPU: $current_cpu") } if (use_partition_alloc_as_malloc_default) { _default_allocator = "partition" } else { _default_allocator = "none" } declare_args() { # Whether PartitionAlloc should be available for use or not. # true makes PartitionAlloc linked to the executable or shared library and # makes it available for use. It doesn't mean that the default allocator # is PartitionAlloc, which is governed by |use_partition_alloc_as_malloc|. # # N.B. generally, embedders should look at this GN arg and at the # corresponding buildflag to determine whether to interact with PA # source at all (pulling the component in via GN, including headers, # etc.). There is nothing stopping a lazy embedder from ignoring this # and unconditionally using PA, but such a setup is inadvisable. # # In Chromium, this is set true, except: # # 1. On Cronet bots, because Cronet doesn't use PartitionAlloc at all, # and doesn't wish to incur the library size increase (crbug.com/674570). # 2. On NaCl (through this declaration), where PartitionAlloc doesn't # build at all. use_partition_alloc = !is_nacl } declare_args() { # PartitionAlloc-Everywhere (PA-E). use_partition_alloc_as_malloc = use_partition_alloc && use_partition_alloc_as_malloc_default } declare_args() { use_freeslot_bitmap = false # Puts the regular and BRP pools right next to each other, so that we can # check "belongs to one of the two pools" with a single bitmask operation. glue_core_pools = false # Introduces pointer compression support in PA. # # This is effective only for memory allocated from PartitionAlloc, so it is # recommended to enable PA-E above, but isn't strictly necessary. Embedders # can create and use PA partitions explicitly. enable_pointer_compression_support = false # Enables a bounds check when two pointers (at least one being raw_ptr) are # subtracted (if supported by the underlying implementation). enable_pointer_subtraction_check = false } declare_args() { # Build support for Use-after-Free protection via BackupRefPtr (BRP), # making the raw_ptr implementation to RawPtrBackupRefImpl if active. # # These are effective only for memory allocated from PartitionAlloc, so it is # recommended to enable PA-E above, but isn't strictly necessary. Embedders # can create and use PA partitions explicitly. # # Note that |enable_backup_ref_ptr_support = true| doesn't necessarily enable # BRP protection. It'll be enabled only for partition created with # partition_alloc::PartitionOptions::BackupRefPtr::kEnabled. enable_backup_ref_ptr_support = use_partition_alloc && enable_backup_ref_ptr_support_default # RAW_PTR_EXCLUSION macro is disabled on official builds because it increased # binary size. This flag can be used to enable it for official builds too. force_enable_raw_ptr_exclusion = false } declare_args() { # Determines whether `raw_ptr_experimental` is an alias for # `raw_ptr` or `T*` (true raw pointer). # # Members rewritten as `raw_ptr_experimental` rely on this as an # escape hatch to degrade to a `T*` if `raw_ptr` performance proves # problematic. Defaults to match standard `raw_ptr` support. # # One side effect of this is that `raw_ptr_experimental foo_` must # not use `foo_.get()`; this is incoherent when `foo_` is a `T*`. # Use `base::to_address()` instead. enable_raw_ptr_experimental = enable_backup_ref_ptr_support } assert(!enable_pointer_compression_support || glue_core_pools, "Pointer compression relies on core pools being contiguous.") declare_args() { # The supported platforms are supposed to match `_is_brp_supported`, but we # enable the feature on Linux early because it's most widely used for security # research. # # The implementation of ASan BRP is purpose-built to inspect Chromium # internals and is entangled with `//base` s.t. it cannot be used # outside of Chromium. use_asan_backup_ref_ptr = build_with_chromium && is_asan && (is_win || is_android || is_linux) # Use probe-on-destruct unowned ptr detection with ASAN. use_asan_unowned_ptr = false } # Use the version of raw_ptr that allows the embedder to implement custom # logic. use_hookable_raw_ptr = use_asan_backup_ref_ptr declare_args() { # - put_ref_count_in_previous_slot: place the ref-count at the end of the # previous slot (or in metadata if a slot starts on the page boundary), as # opposed to the beginning of the slot. # - enable_backup_ref_ptr_slow_checks: enable additional safety checks that # are too expensive to have on by default. # - enable_dangling_raw_ptr_checks: enable checking raw_ptr do not become # dangling during their lifetime. # - backup_ref_ptr_poison_oob_ptr: poison out-of-bounds (OOB) pointers to # generate an exception in the event that an OOB pointer is dereferenced. put_ref_count_in_previous_slot = put_ref_count_in_previous_slot_default && enable_backup_ref_ptr_support enable_backup_ref_ptr_slow_checks = enable_backup_ref_ptr_slow_checks_default && enable_backup_ref_ptr_support # Enable the feature flag required to activate backup ref pointers. That is to # say `PartitionAllocBackupRefPtr`. # # This is meant to be used primarily on bots. It is much easier to override # the feature flags using a binary flag instead of updating multiple bots's # scripts to pass command line arguments. enable_backup_ref_ptr_feature_flag = false enable_dangling_raw_ptr_checks = enable_dangling_raw_ptr_checks_default && enable_backup_ref_ptr_support # Enable the feature flag required to check for dangling pointers. That is to # say `PartitionAllocDanglingPtr`. # # This is meant to be used primarily on bots. It is much easier to override # the feature flags using a binary flag instead of updating multiple bots's # scripts to pass command line arguments. enable_dangling_raw_ptr_feature_flag = false # Enables the dangling raw_ptr checks feature for the performance experiment. # Not every dangling pointers have been fixed or annotated yet. To avoid # accounting for the cost of calling the PA's embedder's callbacks when a # dangling pointer has been detected, this simulates the raw_ptr to be # allowed to dangle. # # This flag is temporary, and isn't used by PA embedders, so it doesn't need # to go through build_overrides enable_dangling_raw_ptr_perf_experiment = false # Set to `enable_backup_ref_ptr_support && has_64_bit_pointers` when enabling. backup_ref_ptr_poison_oob_ptr = false } declare_args() { # Shadow metadata is still under development and only supports Linux # for now. enable_shadow_metadata = false if (is_apple) { # use_blink currently assumes mach absolute ticks (eg, to ensure trace # events cohere). partition_alloc_enable_mach_absolute_time_ticks = is_mac || use_blink } } # *Scan is currently only used by Chromium, and supports only 64-bit. use_starscan = build_with_chromium && has_64_bit_pointers pcscan_stack_supported = use_starscan && (current_cpu == "x64" || current_cpu == "x86" || current_cpu == "arm" || current_cpu == "arm64") # We want to provide assertions that guard against inconsistent build # args, but there is no point in having them fire if we're not building # PartitionAlloc at all. If `use_partition_alloc` is false, we jam all # related args to `false`. The prime example is NaCl, where # PartitionAlloc doesn't build at all. if (is_nacl) { assert(!use_partition_alloc, "PartitionAlloc doesn't build on NaCl") } if (!use_partition_alloc) { use_partition_alloc_as_malloc = false enable_backup_ref_ptr_support = false enable_raw_ptr_experimental = false use_asan_backup_ref_ptr = false use_asan_unowned_ptr = false use_hookable_raw_ptr = false put_ref_count_in_previous_slot = false enable_backup_ref_ptr_slow_checks = false enable_dangling_raw_ptr_checks = false enable_dangling_raw_ptr_perf_experiment = false enable_pointer_subtraction_check = false backup_ref_ptr_poison_oob_ptr = false use_starscan = false } # put_ref_count_in_previous_slot can only be used if # enable_backup_ref_ptr_support is true. assert( enable_backup_ref_ptr_support || !put_ref_count_in_previous_slot, "Can't put ref count in the previous slot if BackupRefPtr isn't enabled at all") # enable_backup_ref_ptr_slow_checks can only be used if enable_backup_ref_ptr_support # is true. assert(enable_backup_ref_ptr_support || !enable_backup_ref_ptr_slow_checks, "Can't enable additional BackupRefPtr checks if it isn't enabled at all") assert( enable_backup_ref_ptr_support || !enable_raw_ptr_experimental, "Can't make `raw_ptr_experimental` = `raw_ptr` when the latter is wholly disabled") # enable_dangling_raw_ptr_checks can only be used if enable_backup_ref_ptr_support # is true. assert( enable_backup_ref_ptr_support || !enable_dangling_raw_ptr_checks, "Can't enable dangling raw_ptr checks if BackupRefPtr isn't enabled at all") # To run the dangling raw_ptr detector experiment, the underlying feature must # be enabled too. assert( enable_dangling_raw_ptr_checks || !enable_dangling_raw_ptr_perf_experiment, "Missing dangling pointer checks feature for its performance experiment") # To poison OOB pointers for BackupRefPtr, the underlying feature must # be enabled, too. assert( enable_backup_ref_ptr_support || !backup_ref_ptr_poison_oob_ptr, "Can't enable poisoning for OOB pointers if BackupRefPtr isn't enabled at all") assert(has_64_bit_pointers || !backup_ref_ptr_poison_oob_ptr, "Can't enable poisoning for OOB pointers if pointers are only 32-bit") # AsanBackupRefPtr and AsanUnownedPtr are mutually exclusive variants of raw_ptr. assert( !use_asan_unowned_ptr || !use_asan_backup_ref_ptr, "Both AsanUnownedPtr and AsanBackupRefPtr can't be enabled at the same time") # BackupRefPtr and AsanBackupRefPtr are mutually exclusive variants of raw_ptr. assert( !enable_backup_ref_ptr_support || !use_asan_backup_ref_ptr, "Both BackupRefPtr and AsanBackupRefPtr can't be enabled at the same time") # BackupRefPtr and AsanUnownedPtr are mutually exclusive variants of raw_ptr. assert(!enable_backup_ref_ptr_support || !use_asan_unowned_ptr, "Both BackupRefPtr and AsanUnownedPtr can't be enabled at the same time") # RawPtrHookableImpl and BackupRefPtr are mutually exclusive variants of raw_ptr. assert( !use_hookable_raw_ptr || !enable_backup_ref_ptr_support, "Both RawPtrHookableImpl and BackupRefPtr can't be enabled at the same time") # RawPtrHookableImpl and AsanUnownedPtr are mutually exclusive variants of raw_ptr. assert( !use_hookable_raw_ptr || !use_asan_unowned_ptr, "Both RawPtrHookableImpl and AsanUnownedPtr can't be enabled at the same time") assert(!use_asan_backup_ref_ptr || is_asan, "AsanBackupRefPtr requires AddressSanitizer") assert(!use_asan_unowned_ptr || is_asan, "AsanUnownedPtr requires AddressSanitizer") if (is_apple) { assert(!use_blink || partition_alloc_enable_mach_absolute_time_ticks, "use_blink requires partition_alloc_enable_mach_absolute_time_ticks") assert(!is_mac || partition_alloc_enable_mach_absolute_time_ticks, "mac requires partition_alloc_enable_mach_absolute_time_ticks") } # AsanBackupRefPtr is not supported outside Chromium. The implementation is # entangled with `//base`. The code is only physically located with the # rest of `raw_ptr` to keep it together. assert(build_with_chromium || !use_asan_backup_ref_ptr, "AsanBackupRefPtr is not supported outside Chromium") assert(!use_asan_backup_ref_ptr || use_hookable_raw_ptr, "AsanBackupRefPtr requires RawPtrHookableImpl") declare_args() { enable_pkeys = is_linux && target_cpu == "x64" && !is_cronet_build } assert(!enable_pkeys || (is_linux && target_cpu == "x64"), "Pkeys are only supported on x64 linux")