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)#include "sandbox/win/src/policy_engine_processor.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace sandbox { 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PolicyProcessor::SetInternalState(size_t index, EvalResult result) { 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state_.current_index_ = index; 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) state_.current_result_ = result; 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)EvalResult PolicyProcessor::GetAction() const { 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return state_.current_result_; 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Decides if an opcode can be skipped (not evaluated) or not. The function 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// takes as inputs the opcode and the current evaluation context and returns 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// true if the opcode should be skipped or not and also can set keep_skipping 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// to false to signal that the current instruction should be skipped but not 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// the next after the current one. 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SkipOpcode(const PolicyOpcode& opcode, MatchContext* context, 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool* keep_skipping) { 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (opcode.IsAction()) { 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) uint32 options = context->options; 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) context->Clear(); 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *keep_skipping = false; 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return (kPolUseOREval != options); 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *keep_skipping = true; 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PolicyResult PolicyProcessor::Evaluate(uint32 options, 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ParameterSet* parameters, 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t param_count) { 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (NULL == policy_) { 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NO_POLICY_MATCH; 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (0 == policy_->opcode_count) { 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NO_POLICY_MATCH; 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!(kShortEval & options)) { 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return POLICY_ERROR; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MatchContext context; 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool evaluation = false; 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool skip_group = false; 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetInternalState(0, EVAL_FALSE); 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) size_t count = policy_->opcode_count; 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Loop over all the opcodes Evaluating in sequence. Since we only support 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // short circuit evaluation, we stop as soon as we find an 'action' opcode 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // and the current evaluation is true. 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Skipping opcodes can happen when we are in AND mode (!kPolUseOREval) and 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // have got EVAL_FALSE or when we are in OR mode (kPolUseOREval) and got 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // EVAL_TRUE. Skipping will stop at the next action opcode or at the opcode 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // after the action depending on kPolUseOREval. 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t ix = 0; ix != count; ++ix) { 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PolicyOpcode& opcode = policy_->opcodes[ix]; 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Skipping block. 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (skip_group) { 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (SkipOpcode(opcode, &context, &skip_group)) { 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Evaluation block. 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EvalResult result = opcode.Evaluate(parameters, param_count, &context); 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (result) { 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case EVAL_FALSE: 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) evaluation = false; 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (kPolUseOREval != context.options) { 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) skip_group = true; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case EVAL_ERROR: 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (kStopOnErrors & options) { 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return POLICY_ERROR; 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case EVAL_TRUE: 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) evaluation = true; 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (kPolUseOREval == context.options) { 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) skip_group = true; 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We have evaluated an action. 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SetInternalState(ix, result); 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return POLICY_MATCH; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (evaluation) { 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Reaching the end of the policy with a positive evaluation is probably 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // an error: we did not find a final action opcode? 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return POLICY_ERROR; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NO_POLICY_MATCH; 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace sandbox 108