policy_low_level.h 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193
  1. // Copyright (c) 2006-2008 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. #ifndef SANDBOX_WIN_SRC_POLICY_LOW_LEVEL_H_
  5. #define SANDBOX_WIN_SRC_POLICY_LOW_LEVEL_H_
  6. #include <stddef.h>
  7. #include <stdint.h>
  8. #include <list>
  9. #include <string>
  10. #include "base/memory/raw_ptr.h"
  11. #include "sandbox/win/src/ipc_tags.h"
  12. #include "sandbox/win/src/policy_engine_opcodes.h"
  13. #include "sandbox/win/src/policy_engine_params.h"
  14. // Low level policy classes.
  15. // Built on top of the PolicyOpcode and OpcodeFactory, the low level policy
  16. // provides a way to define rules on strings and numbers but it is unaware
  17. // of Windows specific details or how the Interceptions must be set up.
  18. // To use these classes you construct one or more rules and add them to the
  19. // LowLevelPolicy object like this:
  20. //
  21. // PolicyRule rule1(ASK_BROKER);
  22. // rule1.AddStringMatch(IF, 0, L"\\\\/?/?\\c:\\*Microsoft*\\*.exe", true);
  23. // rule1.AddNumberMatch(IF_NOT, 1, CREATE_ALWAYS, EQUAL);
  24. // rule1.AddNumberMatch(IF, 2, FILE_ATTRIBUTE_NORMAL, EQUAL);
  25. //
  26. // PolicyRule rule2(FAKE_SUCCESS);
  27. // rule2.AddStringMatch(IF, 0, L"\\\\/?/?\\Pipe\\Chrome.*", false));
  28. // rule2.AddNumberMatch(IF, 1, OPEN_EXISTING, EQUAL));
  29. //
  30. // LowLevelPolicy policyGen(*policy_memory);
  31. // policyGen.AddRule(kNtCreateFileSvc, &rule1);
  32. // policyGen.AddRule(kNtCreateFileSvc, &rule2);
  33. // policyGen.Done();
  34. //
  35. // At this point (error checking omitted) the policy_memory can be copied
  36. // to the target process where it can be evaluated.
  37. namespace sandbox {
  38. // Defines the memory layout of the policy. This memory is filled by
  39. // LowLevelPolicy object.
  40. // For example:
  41. //
  42. // [Service 0] --points to---\
  43. // [Service 1] --------------|-----\
  44. // ...... | |
  45. // [Service N] | |
  46. // [data_size] | |
  47. // [Policy Buffer 0] <-------/ |
  48. // [opcodes of] |
  49. // ....... |
  50. // [Policy Buffer 1] <-------------/
  51. // [opcodes]
  52. // .......
  53. // .......
  54. // [Policy Buffer N]
  55. // [opcodes]
  56. // .......
  57. // <possibly unused space here>
  58. // .......
  59. // [opcode string ]
  60. // [opcode string ]
  61. // .......
  62. // [opcode string ]
  63. struct PolicyGlobal {
  64. PolicyBuffer* entry[kMaxServiceCount];
  65. size_t data_size;
  66. PolicyBuffer data[1];
  67. };
  68. class PolicyRule;
  69. // Provides the means to collect rules into a policy store (memory)
  70. class LowLevelPolicy {
  71. public:
  72. LowLevelPolicy() = delete;
  73. // policy_store: must contain allocated memory and the internal
  74. // size fields set to correct values.
  75. explicit LowLevelPolicy(PolicyGlobal* policy_store);
  76. LowLevelPolicy(const LowLevelPolicy&) = delete;
  77. LowLevelPolicy& operator=(const LowLevelPolicy&) = delete;
  78. // Destroys all the policy rules.
  79. ~LowLevelPolicy();
  80. // Adds a rule to be generated when Done() is called.
  81. // service: The id of the service that this rule is associated with,
  82. // for example the 'Open Thread' service or the "Create File" service.
  83. // returns false on error.
  84. bool AddRule(IpcTag service, PolicyRule* rule);
  85. // Generates all the rules added with AddRule() into the memory area
  86. // passed on the constructor. Returns false on error.
  87. bool Done();
  88. private:
  89. struct RuleNode {
  90. const PolicyRule* rule;
  91. IpcTag service;
  92. };
  93. std::list<RuleNode> rules_;
  94. raw_ptr<PolicyGlobal> policy_store_;
  95. };
  96. // There are 'if' rules and 'if not' comparisons
  97. enum RuleType {
  98. IF = 0,
  99. IF_NOT = 1,
  100. };
  101. // Possible comparisons for numbers
  102. enum RuleOp {
  103. EQUAL,
  104. AND,
  105. RANGE // TODO(cpu): Implement this option.
  106. };
  107. // Provides the means to collect a set of comparisons into a single
  108. // rule and its associated action.
  109. class PolicyRule {
  110. friend class LowLevelPolicy;
  111. public:
  112. explicit PolicyRule(EvalResult action);
  113. PolicyRule(const PolicyRule& other);
  114. ~PolicyRule();
  115. // Adds a string comparison to the rule.
  116. // rule_type: possible values are IF and IF_NOT.
  117. // parameter: the expected index of the argument for this rule. For example
  118. // in a 'create file' service the file name argument can be at index 0.
  119. // string: is the desired matching pattern.
  120. // match_opts: if the pattern matching is case sensitive or not.
  121. bool AddStringMatch(RuleType rule_type,
  122. int16_t parameter,
  123. const wchar_t* string,
  124. StringMatchOptions match_opts);
  125. // Adds a number match comparison to the rule.
  126. // rule_type: possible values are IF and IF_NOT.
  127. // parameter: the expected index of the argument for this rule.
  128. // number: the value to compare the input to.
  129. // comparison_op: the comparison kind (equal, logical and, etc).
  130. bool AddNumberMatch(RuleType rule_type,
  131. int16_t parameter,
  132. uint32_t number,
  133. RuleOp comparison_op);
  134. // Returns the number of opcodes generated so far.
  135. size_t GetOpcodeCount() const { return buffer_->opcode_count; }
  136. // Called when there is no more comparisons to add. Internally it generates
  137. // the last opcode (the action opcode). Returns false if this operation fails.
  138. bool Done();
  139. private:
  140. void operator=(const PolicyRule&);
  141. // Called in a loop from AddStringMatch to generate the required string
  142. // match opcodes. rule_type, match_opts and parameter are the same as
  143. // in AddStringMatch.
  144. bool GenStringOpcode(RuleType rule_type,
  145. StringMatchOptions match_opts,
  146. uint16_t parameter,
  147. int state,
  148. bool last_call,
  149. int* skip_count,
  150. std::wstring* fragment);
  151. // Loop over all generated opcodes and copy them to increasing memory
  152. // addresses from opcode_start and copy the extra data (strings usually) into
  153. // decreasing addresses from data_start. Extra data is only present in the
  154. // string evaluation opcodes.
  155. bool RebindCopy(PolicyOpcode* opcode_start,
  156. size_t opcode_size,
  157. char* data_start,
  158. size_t* data_size) const;
  159. raw_ptr<PolicyBuffer> buffer_;
  160. raw_ptr<OpcodeFactory> opcode_factory_;
  161. EvalResult action_;
  162. bool done_;
  163. };
  164. } // namespace sandbox
  165. #endif // SANDBOX_WIN_SRC_POLICY_LOW_LEVEL_H_