1 // Copyright 2021 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_STARSCAN_WRITE_PROTECTOR_H_
6 #define PARTITION_ALLOC_STARSCAN_WRITE_PROTECTOR_H_
7 
8 #include <cstddef>
9 #include <cstdint>
10 #include <mutex>
11 
12 #include "build/build_config.h"
13 #include "partition_alloc/internal_allocator_forward.h"
14 #include "partition_alloc/starscan/pcscan.h"
15 #include "partition_alloc/starscan/raceful_worklist.h"
16 
17 namespace partition_alloc::internal {
18 
19 // Interface for page protection/unprotection. This is used in DCScan to catch
20 // concurrent mutator writes. Protection is done when the scanner starts
21 // scanning a range. Unprotection happens at the end of the scanning phase.
22 class WriteProtector : public internal::InternalPartitionAllocated {
23  public:
24   virtual ~WriteProtector() = default;
25 
26   virtual void ProtectPages(uintptr_t begin, size_t length) = 0;
27   virtual void UnprotectPages(uintptr_t begin, size_t length) = 0;
28 
29   virtual bool IsEnabled() const = 0;
30 
31   virtual PCScan::ClearType SupportedClearType() const = 0;
32 };
33 
34 class NoWriteProtector final : public WriteProtector {
35  public:
ProtectPages(uintptr_t,size_t)36   void ProtectPages(uintptr_t, size_t) final {}
UnprotectPages(uintptr_t,size_t)37   void UnprotectPages(uintptr_t, size_t) final {}
38   PCScan::ClearType SupportedClearType() const final;
39   inline bool IsEnabled() const override;
40 };
41 
IsEnabled()42 bool NoWriteProtector::IsEnabled() const {
43   return false;
44 }
45 
46 #if PA_CONFIG(STARSCAN_UFFD_WRITE_PROTECTOR_SUPPORTED)
47 class UserFaultFDWriteProtector final : public WriteProtector {
48  public:
49   UserFaultFDWriteProtector();
50 
51   UserFaultFDWriteProtector(const UserFaultFDWriteProtector&) = delete;
52   UserFaultFDWriteProtector& operator=(const UserFaultFDWriteProtector&) =
53       delete;
54 
55   void ProtectPages(uintptr_t, size_t) final;
56   void UnprotectPages(uintptr_t, size_t) final;
57 
58   PCScan::ClearType SupportedClearType() const final;
59 
60   inline bool IsEnabled() const override;
61 
62  private:
63   bool IsSupported() const;
64 
65   const int uffd_ = 0;
66 };
67 
IsEnabled()68 bool UserFaultFDWriteProtector::IsEnabled() const {
69   return IsSupported();
70 }
71 #endif  // PA_CONFIG(STARSCAN_UFFD_WRITE_PROTECTOR_SUPPORTED)
72 
73 }  // namespace partition_alloc::internal
74 
75 #endif  // PARTITION_ALLOC_STARSCAN_WRITE_PROTECTOR_H_
76