15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#ifndef SANDBOX_SRC_POLICY_LOW_LEVEL_H__ 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define SANDBOX_SRC_POLICY_LOW_LEVEL_H__ 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <list> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/strings/string16.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/ipc_tags.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/policy_engine_params.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sandbox/win/src/policy_engine_opcodes.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Low level policy classes. 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Built on top of the PolicyOpcode and OpcodeFatory, the low level policy 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// provides a way to define rules on strings and numbers but it is unaware 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// of Windows specific details or how the Interceptions must be set up. 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// To use these classes you construct one or more rules and add them to the 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LowLevelPolicy object like this: 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// PolicyRule rule1(ASK_BROKER); 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// rule1.AddStringMatch(IF, 0, L"\\\\/?/?\\c:\\*Microsoft*\\*.exe", true); 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// rule1.AddNumberMatch(IF_NOT, 1, CREATE_ALWAYS, EQUAL); 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// rule1.AddNumberMatch(IF, 2, FILE_ATTRIBUTE_NORMAL, EQUAL); 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// PolicyRule rule2(FAKE_SUCCESS); 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// rule2.AddStringMatch(IF, 0, L"\\\\/?/?\\Pipe\\Chrome.*", false)); 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// rule2.AddNumberMatch(IF, 1, OPEN_EXISTING, EQUAL)); 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LowLevelPolicy policyGen(*policy_memory); 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// policyGen.AddRule(kNtCreateFileSvc, &rule1); 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// policyGen.AddRule(kNtCreateFileSvc, &rule2); 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// policyGen.Done(); 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// At this point (error checking omitted) the policy_memory can be copied 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to the target process where it can be evaluated. 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace sandbox { 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(cpu): Move this constant to crosscall_client.h. 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const size_t kMaxServiceCount = 32; 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)COMPILE_ASSERT(IPC_LAST_TAG <= kMaxServiceCount, kMaxServiceCount_is_too_low); 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Defines the memory layout of the policy. This memory is filled by 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LowLevelPolicy object. 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// For example: 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// [Service 0] --points to---\ 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// [Service 1] --------------|-----\ 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ...... | | 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// [Service N] | | 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// [data_size] | | 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// [Policy Buffer 0] <-------/ | 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// [opcodes of] | 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ....... | 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// [Policy Buffer 1] <-------------/ 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// [opcodes] 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ....... 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ....... 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// [Policy Buffer N] 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// [opcodes] 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ....... 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// <possibly unused space here> 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ....... 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// [opcode string ] 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// [opcode string ] 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ....... 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// [opcode string ] 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct PolicyGlobal { 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PolicyBuffer* entry[kMaxServiceCount]; 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t data_size; 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PolicyBuffer data[1]; 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PolicyRule; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Provides the means to collect rules into a policy store (memory) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class LowLevelPolicy { 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // policy_store: must contain allocated memory and the internal 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // size fields set to correct values. 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit LowLevelPolicy(PolicyGlobal* policy_store) 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : policy_store_(policy_store) { 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Destroys all the policy rules. 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~LowLevelPolicy(); 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Adds a rule to be generated when Done() is called. 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // service: The id of the service that this rule is associated with, 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // for example the 'Open Thread' service or the "Create File" service. 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // returns false on error. 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool AddRule(int service, PolicyRule* rule); 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Generates all the rules added with AddRule() into the memory area 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // passed on the constructor. Returns false on error. 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool Done(); 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct RuleNode { 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PolicyRule* rule; 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int service; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::list<RuleNode> rules_; 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PolicyGlobal* policy_store_; 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_IMPLICIT_CONSTRUCTORS(LowLevelPolicy); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// There are 'if' rules and 'if not' comparisons 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum RuleType { 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IF = 0, 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IF_NOT = 1, 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Possible comparisons for numbers 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)enum RuleOp { 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EQUAL, 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AND, 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RANGE // TODO(cpu): Implement this option. 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Provides the means to collect a set of comparisons into a single 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// rule and its associated action. 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class PolicyRule { 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class LowLevelPolicy; 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit PolicyRule(EvalResult action); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PolicyRule(const PolicyRule& other); 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~PolicyRule(); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Adds a string comparison to the rule. 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // rule_type: possible values are IF and IF_NOT. 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // parameter: the expected index of the argument for this rule. For example 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // in a 'create file' service the file name argument can be at index 0. 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // string: is the desired matching pattern. 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // match_opts: if the pattern matching is case sensitive or not. 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool AddStringMatch(RuleType rule_type, int16 parameter, 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const wchar_t* string, StringMatchOptions match_opts); 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Adds a number match comparison to the rule. 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // rule_type: possible values are IF and IF_NOT. 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // parameter: the expected index of the argument for this rule. 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // number: the value to compare the input to. 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // comparison_op: the comparison kind (equal, logical and, etc). 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool AddNumberMatch(RuleType rule_type, int16 parameter, 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unsigned long number, RuleOp comparison_op); 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Returns the number of opcodes generated so far. 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t GetOpcodeCount() const { 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return buffer_->opcode_count; 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Called when there is no more comparisons to add. Internally it generates 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the last opcode (the action opcode). Returns false if this operation fails. 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool Done(); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void operator=(const PolicyRule&); 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Called in a loop from AddStringMatch to generate the required string 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // match opcodes. rule_type, match_opts and parameter are the same as 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // in AddStringMatch. 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool GenStringOpcode(RuleType rule_type, StringMatchOptions match_opts, 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint16 parameter, int state, bool last_call, 1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int* skip_count, base::string16* fragment); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Loop over all generated opcodes and copy them to increasing memory 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // addresses from opcode_start and copy the extra data (strings usually) into 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // decreasing addresses from data_start. Extra data is only present in the 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // string evaluation opcodes. 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool RebindCopy(PolicyOpcode* opcode_start, size_t opcode_size, 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) char* data_start, size_t* data_size) const; 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PolicyBuffer* buffer_; 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OpcodeFactory* opcode_factory_; 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EvalResult action_; 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool done_; 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace sandbox 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // SANDBOX_SRC_POLICY_LOW_LEVEL_H__ 184