1 : // Copyright 2014 Google Inc. All Rights Reserved.
2 : //
3 : // Licensed under the Apache License, Version 2.0 (the "License");
4 : // you may not use this file except in compliance with the License.
5 : // You may obtain a copy of the License at
6 : //
7 : // http://www.apache.org/licenses/LICENSE-2.0
8 : //
9 : // Unless required by applicable law or agreed to in writing, software
10 : // distributed under the License is distributed on an "AS IS" BASIS,
11 : // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 : // See the License for the specific language governing permissions and
13 : // limitations under the License.
14 : //
15 : // Collection of functions and objects for modifying page protections in a
16 : // consistent way.
17 :
18 : #ifndef SYZYGY_AGENT_ASAN_PAGE_PROTECTION_HELPERS_H_
19 : #define SYZYGY_AGENT_ASAN_PAGE_PROTECTION_HELPERS_H_
20 :
21 : #include "syzygy/agent/asan/block.h"
22 : #include "syzygy/agent/asan/shadow.h"
23 : #include "syzygy/common/recursive_lock.h"
24 :
25 : namespace agent {
26 : namespace asan {
27 :
28 : // A global recursive lock. This gates all access to block protection
29 : // functions. This is exposed for crash processing, which wants to block
30 : // other threads from tinkering with page protections.
31 : extern ::common::RecursiveLock block_protect_lock;
32 :
33 : // Given a pointer to the body of a block extracts its layout. If the block
34 : // header is not under any block protections then the layout will be read from
35 : // the header. If the header is corrupt, or the memory is otherwise unreadable,
36 : // this will be inferred from the shadow memory (less efficient, but not subject
37 : // to corruption).
38 : // @param raw_block A pointer to the beginning of the block.
39 : // @param block_info The description of the block to be populated.
40 : // @returns true if a valid block was encountered at the provided location,
41 : // false otherwise.
42 : bool GetBlockInfo(const void* raw_block, CompactBlockInfo* block_info);
43 : bool GetBlockInfo(const void* raw_block, BlockInfo* block_info);
44 :
45 : // Unprotects all pages fully covered by the given block. All pages
46 : // intersecting but not fully covered by the block will be left in their
47 : // current state.
48 : // @param block_info The block whose protections are to be modified.
49 : // @note Under block_protect_lock.
50 : void BlockProtectNone(const BlockInfo& block_info);
51 :
52 : // Protects all entire pages that are spanned by the redzones of the
53 : // block. All pages intersecting the body of the block will be explicitly
54 : // unprotected. All pages not intersecting the body but only partially
55 : // covered by the redzone will be left in their current state.
56 : // @param block_info The block whose protections are to be modified.
57 : // @note Under block_protect_lock.
58 : void BlockProtectRedzones(const BlockInfo& block_info);
59 :
60 : // Protects all pages completely spanned by the block. All pages
61 : // intersecting but not fully covered by the block will be left in their
62 : // current state.
63 : // @param block_info The block whose protections are to be modified.
64 : // @note Under block_protect_lock.
65 : void BlockProtectAll(const BlockInfo& block_info);
66 :
67 : // Sets the block protections according to the block state. If in the allocated
68 : // state uses BlockProtectRedzones. If in quarantined or freed uses
69 : // BlockProtectAll.
70 : // @param block_info The block whose protections are to be modified.
71 : // @note Under block_protect_lock.
72 : void BlockProtectAuto(const BlockInfo& block_info);
73 :
74 : // A scoped block access helper. Removes block protections when created via
75 : // BlockProtectNone, and restores them via BlockProtectAuto.
76 : // TODO(chrisha): Consider recording the fact the block protections on this
77 : // block are being blocked in some synchronous manner. This will prevent
78 : // the page protections from being added during the lifetime of this
79 : // object.
80 : class ScopedBlockAccess {
81 : public:
82 : // Constructor. Unprotects the provided block.
83 : // @param block_info The block whose protections are to be modified.
84 E : explicit ScopedBlockAccess(const BlockInfo& block_info)
85 : : block_info_(block_info) {
86 E : BlockProtectNone(block_info_);
87 E : }
88 :
89 : // Destructor. Restores protections on the provided block.
90 E : ~ScopedBlockAccess() {
91 E : BlockProtectAuto(block_info_);
92 E : }
93 :
94 : private:
95 : const BlockInfo& block_info_;
96 : };
97 :
98 : } // namespace asan
99 : } // namespace agent
100 :
101 : #endif // SYZYGY_AGENT_ASAN_PAGE_PROTECTION_HELPERS_H_
|