summaryrefslogtreecommitdiffstats
path: root/sandbox/src/policy_low_level.h
diff options
context:
space:
mode:
Diffstat (limited to 'sandbox/src/policy_low_level.h')
-rw-r--r--sandbox/src/policy_low_level.h207
1 files changed, 207 insertions, 0 deletions
diff --git a/sandbox/src/policy_low_level.h b/sandbox/src/policy_low_level.h
new file mode 100644
index 0000000..0adaf11
--- /dev/null
+++ b/sandbox/src/policy_low_level.h
@@ -0,0 +1,207 @@
+// Copyright 2008, Google Inc.
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following disclaimer
+// in the documentation and/or other materials provided with the
+// distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived from
+// this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#ifndef SANDBOX_SRC_POLICY_LOW_LEVEL_H__
+#define SANDBOX_SRC_POLICY_LOW_LEVEL_H__
+
+#include <list>
+
+#include "base/basictypes.h"
+#include "sandbox/src/ipc_tags.h"
+#include "sandbox/src/policy_engine_params.h"
+#include "sandbox/src/policy_engine_opcodes.h"
+
+// Low level policy classes.
+// Built on top of the PolicyOpcode and OpcodeFatory, the low level policy
+// provides a way to define rules on strings and numbers but it is unaware
+// of Windows specific details or how the Interceptions must be set up.
+// To use these classes you construct one or more rules and add them to the
+// LowLevelPolicy object like this:
+//
+// PolicyRule rule1(ASK_BROKER);
+// rule1.AddStringMatch(IF, 0, L"\\\\/?/?\\c:\\*Microsoft*\\*.exe", true);
+// rule1.AddNumberMatch(IF_NOT, 1, CREATE_ALWAYS, EQUAL);
+// rule1.AddNumberMatch(IF, 2, FILE_ATTRIBUTE_NORMAL, EQUAL);
+//
+// PolicyRule rule2(FAKE_SUCCESS);
+// rule2.AddStringMatch(IF, 0, L"\\\\/?/?\\Pipe\\Chrome.*", false));
+// rule2.AddNumberMatch(IF, 1, OPEN_EXISTING, EQUAL));
+//
+// LowLevelPolicy policyGen(*policy_memory);
+// policyGen.AddRule(kNtCreateFileSvc, &rule1);
+// policyGen.AddRule(kNtCreateFileSvc, &rule2);
+// policyGen.Done();
+//
+// At this point (error checking omitted) the policy_memory can be copied
+// to the target process where it can be evaluated.
+
+namespace sandbox {
+
+// TODO(cpu): Move this constant to crosscall_client.h.
+const size_t kMaxServiceCount = 32;
+COMPILE_ASSERT(IPC_LAST_TAG <= kMaxServiceCount, kMaxServiceCount_is_too_low);
+
+// Defines the memory layout of the policy. This memory is filled by
+// LowLevelPolicy object.
+// For example:
+//
+// [Service 0] --points to---\
+// [Service 1] --------------|-----\
+// ...... | |
+// [Service N] | |
+// [data_size] | |
+// [Policy Buffer 0] <-------/ |
+// [opcodes of] |
+// ....... |
+// [Policy Buffer 1] <-------------/
+// [opcodes]
+// .......
+// .......
+// [Policy Buffer N]
+// [opcodes]
+// .......
+// <possibly unused space here>
+// .......
+// [opcode string ]
+// [opcode string ]
+// .......
+// [opcode string ]
+struct PolicyGlobal {
+ PolicyBuffer* entry[kMaxServiceCount];
+ size_t data_size;
+ PolicyBuffer data[1];
+};
+
+class PolicyRule;
+
+// Provides the means to collect rules into a policy store (memory)
+class LowLevelPolicy {
+ public:
+ // policy_store: must contain allocated memory and the internal
+ // size fields set to correct values.
+ explicit LowLevelPolicy(PolicyGlobal* policy_store)
+ : policy_store_(policy_store) {
+ }
+
+ // Destroys all the policy rules.
+ ~LowLevelPolicy();
+
+ // Adds a rule to be generated when Done() is called.
+ // service: The id of the service that this rule is associated with,
+ // for example the 'Open Thread' service or the "Create File" service.
+ // returns false on error.
+ bool AddRule(int service, PolicyRule* rule);
+
+ // Generates all the rules added with AddRule() into the memory area
+ // passed on the constructor. Returns false on error.
+ bool Done();
+
+ private:
+ struct RuleNode {
+ const PolicyRule* rule;
+ int service;
+ };
+ std::list<RuleNode> rules_;
+ PolicyGlobal* policy_store_;
+ DISALLOW_IMPLICIT_CONSTRUCTORS(LowLevelPolicy);
+};
+
+// There are 'if' rules and 'if not' comparisons
+enum RuleType {
+ IF = 0,
+ IF_NOT = 1,
+};
+
+// Possible comparisons for numbers
+enum RuleOp {
+ EQUAL,
+ AND,
+ RANGE // TODO(cpu): Implement this option.
+};
+
+// Provides the means to collect a set of comparisons into a single
+// rule and its associated action.
+class PolicyRule {
+ friend class LowLevelPolicy;
+
+ public:
+ explicit PolicyRule(EvalResult action);
+ PolicyRule(const PolicyRule& other);
+ ~PolicyRule();
+
+ // Adds a string comparison to the rule.
+ // rule_type: possible values are IF and IF_NOT.
+ // parameter: the expected index of the argument for this rule. For example
+ // in a 'create file' service the file name argument can be at index 0.
+ // string: is the desired matching pattern.
+ // match_opts: if the pattern matching is case sensitive or not.
+ bool AddStringMatch(RuleType rule_type, int16 parameter,
+ const wchar_t* string, StringMatchOptions match_opts);
+
+ // Adds a number match comparison to the rule.
+ // rule_type: possible values are IF and IF_NOT.
+ // parameter: the expected index of the argument for this rule.
+ // number: the value to compare the input to.
+ // comparison_op: the comparison kind (equal, logical and, etc).
+ bool AddNumberMatch(RuleType rule_type, int16 parameter,
+ unsigned long number, RuleOp comparison_op);
+
+ // Returns the number of opcodes generated so far.
+ size_t GetOpcodeCount() const {
+ return buffer_->opcode_count;
+ }
+
+ // Called when there is no more comparisons to add. Internally it generates
+ // the last opcode (the action opcode). Returns false if this operation fails.
+ bool Done();
+
+ private:
+ void operator=(const PolicyRule&);
+ // Called in a loop from AddStringMatch to generate the required string
+ // match opcodes. rule_type, match_opts and parameter are the same as
+ // in AddStringMatch.
+ bool GenStringOpcode(RuleType rule_type, StringMatchOptions match_opts,
+ uint16 parameter, int state, bool last_call,
+ int* skip_count, std::wstring* fragment);
+
+ // Loop over all generated opcodes and copy them to increasing memory
+ // addresses from opcode_start and copy the extra data (strings usually) into
+ // decreasing addresses from data_start. Extra data is only present in the
+ // string evaluation opcodes.
+ bool RebindCopy(PolicyOpcode* opcode_start, size_t opcode_size,
+ char* data_start, size_t* data_size) const;
+ PolicyBuffer* buffer_;
+ OpcodeFactory* opcode_factory_;
+ EvalResult action_;
+ bool done_;
+};
+
+} // namespace sandbox
+
+#endif // SANDBOX_SRC_POLICY_LOW_LEVEL_H__