1 // Copyright 2020 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #ifndef BASE_ALLOCATOR_PARTITION_ALLOCATOR_PARTITION_ALLOC_FEATURES_H_
6 #define BASE_ALLOCATOR_PARTITION_ALLOCATOR_PARTITION_ALLOC_FEATURES_H_
7 
8 #include "base/allocator/buildflags.h"
9 #include "base/allocator/partition_allocator/partition_alloc_constants.h"
10 #include "base/base_export.h"
11 #include "base/feature_list.h"
12 #include "base/metrics/field_trial_params.h"
13 #include "build/build_config.h"
14 
15 #if defined(OS_WIN)
16 // VersionHelpers.h depends on Windows.h.
17 #include <Windows.h>
18 // For IsWindows8Point1OrGreater().
19 #include <VersionHelpers.h>
20 #endif
21 
22 #define ALLOW_ENABLING_PCSCAN 0
23 
24 namespace base {
25 
26 struct Feature;
27 
28 namespace features {
29 
30 extern const BASE_EXPORT Feature kPartitionAllocGigaCage;
31 extern const BASE_EXPORT Feature kPartitionAllocPCScan;
32 
IsPartitionAllocGigaCageEnabled()33 ALWAYS_INLINE bool IsPartitionAllocGigaCageEnabled() {
34 #if defined(PA_HAS_64_BITS_POINTERS) && defined(OS_WIN)
35   // Lots of crashes (at PartitionAddressSpace::Init) occur
36   // when enabling GigaCage on Windows whose version is smaller than 8.1,
37   // because PTEs for reserved memory counts against commit limit. See
38   // https://crbug.com/1101421.
39   // TODO(tasak): this windows version check is the same as GetRandomPageBase()
40   // (address_space_randomization.cc). Refactor the code to avoid the
41   // duplication.
42   static bool is_windows_version_checked = false;
43   // Don't assign directly IsWindows8Point1OrGreater() to a static local
44   // variable, because the initial value is not trivial and the assignment needs
45   // thread-safe static-local initializer on Windows. (i.e. Init_thread_header)
46   // This causes issues when used on the allocation path (see
47   // crbug.com/1126432). As we don't use atomics here, this may end up querying
48   // the version multiple times, which is fine, as this operation is idempotent,
49   // with no side-effects.
50   static bool recent_enough_windows_version = false;
51   if (!is_windows_version_checked) {
52     recent_enough_windows_version = IsWindows8Point1OrGreater();
53     is_windows_version_checked = true;
54   }
55   if (!recent_enough_windows_version)
56     return false;
57 #endif  // defined(PA_HAS_64_BITS_POINTERS) && defined(OS_WIN)
58 #if BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC)
59   return true;
60 #else
61   return FeatureList::IsEnabled(kPartitionAllocGigaCage);
62 #endif  // BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC)
63 }
64 
IsPartitionAllocPCScanEnabled()65 ALWAYS_INLINE bool IsPartitionAllocPCScanEnabled() {
66 #if !defined(PA_HAS_64_BITS_POINTERS) || !ALLOW_ENABLING_PCSCAN
67   return false;
68 #endif
69   // TODO(bikineev): Calling this function can allocate which can cause
70   // reentrancy for the 'PA as malloc' configuration.
71   return FeatureList::IsEnabled(kPartitionAllocPCScan);
72 }
73 
74 }  // namespace features
75 }  // namespace base
76 
77 #endif  // BASE_ALLOCATOR_PARTITION_ALLOCATOR_PARTITION_ALLOC_FEATURES_H_
78