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