Fix crash on app list start page keyboard navigation with <4 apps.
[chromium-blink-merge.git] / sandbox / linux / syscall_broker / broker_policy.cc
blobd9f69e3b8111f27dcfdab1c86cac1d7af1bd11b6
1 // Copyright 2014 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.
5 #include "sandbox/linux/syscall_broker/broker_policy.h"
7 #include <fcntl.h>
8 #include <stdint.h>
9 #include <string.h>
11 #include <string>
12 #include <vector>
14 #include "base/logging.h"
15 #include "sandbox/linux/syscall_broker/broker_common.h"
17 namespace sandbox {
18 namespace syscall_broker {
20 BrokerPolicy::BrokerPolicy(int denied_errno,
21 const std::vector<BrokerFilePermission>& permissions)
22 : denied_errno_(denied_errno),
23 permissions_(permissions),
24 num_of_permissions_(permissions.size()) {
25 // The spec guarantees vectors store their elements contiguously
26 // so set up a pointer to array of element so it can be used
27 // in async signal safe code instead of vector operations.
28 if (num_of_permissions_ > 0) {
29 permissions_array_ = &permissions_[0];
30 } else {
31 permissions_array_ = NULL;
35 BrokerPolicy::~BrokerPolicy() {
38 // Check if calling access() should be allowed on |requested_filename| with
39 // mode |requested_mode|.
40 // Note: access() being a system call to check permissions, this can get a bit
41 // confusing. We're checking if calling access() should even be allowed with
42 // the same policy we would use for open().
43 // If |file_to_access| is not NULL, we will return the matching pointer from
44 // the whitelist. For paranoia a caller should then use |file_to_access|. See
45 // GetFileNameIfAllowedToOpen() for more explanation.
46 // return true if calling access() on this file should be allowed, false
47 // otherwise.
48 // Async signal safe if and only if |file_to_access| is NULL.
49 bool BrokerPolicy::GetFileNameIfAllowedToAccess(
50 const char* requested_filename,
51 int requested_mode,
52 const char** file_to_access) const {
53 if (file_to_access && *file_to_access) {
54 // Make sure that callers never pass a non-empty string. In case callers
55 // wrongly forget to check the return value and look at the string
56 // instead, this could catch bugs.
57 RAW_LOG(FATAL, "*file_to_access should be NULL");
58 return false;
60 for (size_t i = 0; i < num_of_permissions_; i++) {
61 if (permissions_array_[i].CheckAccess(requested_filename, requested_mode,
62 file_to_access)) {
63 return true;
66 return false;
69 // Check if |requested_filename| can be opened with flags |requested_flags|.
70 // If |file_to_open| is not NULL, we will return the matching pointer from the
71 // whitelist. For paranoia, a caller should then use |file_to_open| rather
72 // than |requested_filename|, so that it never attempts to open an
73 // attacker-controlled file name, even if an attacker managed to fool the
74 // string comparison mechanism.
75 // Return true if opening should be allowed, false otherwise.
76 // Async signal safe if and only if |file_to_open| is NULL.
77 bool BrokerPolicy::GetFileNameIfAllowedToOpen(const char* requested_filename,
78 int requested_flags,
79 const char** file_to_open,
80 bool* unlink_after_open) const {
81 if (file_to_open && *file_to_open) {
82 // Make sure that callers never pass a non-empty string. In case callers
83 // wrongly forget to check the return value and look at the string
84 // instead, this could catch bugs.
85 RAW_LOG(FATAL, "*file_to_open should be NULL");
86 return false;
88 for (size_t i = 0; i < num_of_permissions_; i++) {
89 if (permissions_array_[i].CheckOpen(requested_filename, requested_flags,
90 file_to_open, unlink_after_open)) {
91 return true;
94 return false;
97 } // namespace syscall_broker
99 } // namespace sandbox