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
5 #ifndef PARTITION_ALLOC_GWP_ASAN_SUPPORT_H_
6 #define PARTITION_ALLOC_GWP_ASAN_SUPPORT_H_
7
8 #include "partition_alloc/partition_alloc_base/component_export.h"
9 #include "partition_alloc/partition_alloc_buildflags.h"
10
11 #if BUILDFLAG(ENABLE_GWP_ASAN_SUPPORT)
12
13 #include <cstddef>
14 #include <cstdint>
15 #include <vector>
16
17 namespace partition_alloc {
18
19 // This class allows GWP-ASan allocations to be backed by PartitionAlloc and,
20 // consequently, protected by MiraclePtr.
21 //
22 // GWP-ASan mainly operates at the system memory page granularity. During
23 // process startup, it reserves a certain number of consecutive system pages.
24 //
25 // The standard layout is as follows:
26 //
27 // +-------------------+--------
28 // | | ▲ ▲
29 // | system page 0 |(a) (c)
30 // | | ▼ ▼
31 // +-------------------+--------
32 // | | ▲ ▲
33 // | system page 1 |(b) |
34 // | | ▼ |
35 // +-------------------+--- (d) (a) inaccessible
36 // | | ▲ | (b) accessible
37 // | system page 2 |(a) | (c) initial guard page
38 // | | ▼ ▼ (d) allocation slot
39 // +-------------------+--------
40 // | | ▲ ▲
41 // | system page 3 |(b) |
42 // | | ▼ |
43 // +-------------------+--- (d)
44 // | | ▲ |
45 // | system page 4 |(a) |
46 // | | ▼ ▼
47 // |-------------------|--------
48 // | | ▲ ▲
49 // | ... |(a) (d)
50 //
51 // Unfortunately, PartitionAlloc can't provide GWP-ASan an arbitrary number of
52 // consecutive allocation slots. Allocations need to be grouped into 2MB super
53 // pages so that the allocation metadata can be easily located.
54 //
55 // Below is the new layout:
56 //
57 // +-----------------------------------
58 // | | ▲ ▲
59 // | system page 0 | | |
60 // | | | |
61 // +-------------------+ | |
62 // | | | |
63 // | ... | (e) |
64 // | | | |
65 // +-------------------+------- | |
66 // | | ▲ ▲ | |
67 // | system page k-1 |(a) (c) | |
68 // | | ▼ ▼ ▼ |
69 // +-------------------+----------- (f)
70 // | | ▲ ▲ |
71 // | system page k |(b) | |
72 // | | ▼ | |
73 // +-------------------+--- (d) |
74 // | | ▲ | |
75 // | system page k+1 |(a) | |
76 // | | ▼ ▼ |
77 // +-------------------+----------- |
78 // | | | (a) inaccessible
79 // | ... | | (b) accessible
80 // | | ▼ (c) initial guard page
81 // +----------------------------------- (d) allocation slot
82 // | | ▲ ▲ (e) super page metadata
83 // | system page m | | | (f) super page
84 // | | | | (g) pseudo allocation slot
85 // +-------------------+------- | |
86 // | | ▲ | |
87 // | ... | | (e) |
88 // | | | | |
89 // +-------------------+--- (g) | |
90 // | | ▲ | | |
91 // | system page m+k-1 |(a) | | |
92 // | | ▼ ▼ ▼ |
93 // +-------------------+----------- (f)
94 // | | ▲ ▲ |
95 // | system page m+k |(b) | |
96 // | | ▼ | |
97 // +-------------------+--- (d) |
98 // | | ▲ | |
99 // | system page m+k+1 |(a) | |
100 // | | ▼ ▼ |
101 // +-------------------+----------- |
102 // | | |
103 // | ... | |
104 // | | ▼
105 // +-------------------+---------------
106 //
107 // This means some allocation slots will be reserved to hold PA
108 // metadata. We exclude these pseudo slots from the GWP-ASan free list so that
109 // they are never used for anything other that storing the metadata.
PA_COMPONENT_EXPORT(PARTITION_ALLOC)110 class PA_COMPONENT_EXPORT(PARTITION_ALLOC) GwpAsanSupport {
111 public:
112 static void* MapRegion(size_t slot_count, std::vector<uint16_t>& free_list);
113 static bool CanReuse(uintptr_t slot_start);
114 };
115
116 } // namespace partition_alloc
117
118 #endif // BUILDFLAG(ENABLE_GWP_ASAN_SUPPORT)
119
120 #endif // PARTITION_ALLOC_GWP_ASAN_SUPPORT_H_
121