| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "sandbox/linux/syscall_broker/broker_host.h" | 5 #include "sandbox/linux/syscall_broker/broker_host.h" |
| 6 | 6 |
| 7 #include <fcntl.h> | 7 #include <fcntl.h> |
| 8 #include <sys/socket.h> | 8 #include <sys/socket.h> |
| 9 #include <sys/stat.h> | 9 #include <sys/stat.h> |
| 10 #include <sys/syscall.h> | 10 #include <sys/syscall.h> |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 52 return syscall(__NR_openat, AT_FDCWD, pathname, flags, mode); | 52 return syscall(__NR_openat, AT_FDCWD, pathname, flags, mode); |
| 53 } | 53 } |
| 54 } | 54 } |
| 55 | 55 |
| 56 // Open |requested_filename| with |flags| if allowed by our policy. | 56 // Open |requested_filename| with |flags| if allowed by our policy. |
| 57 // Write the syscall return value (-errno) to |write_pickle| and append | 57 // Write the syscall return value (-errno) to |write_pickle| and append |
| 58 // a file descriptor to |opened_files| if relevant. | 58 // a file descriptor to |opened_files| if relevant. |
| 59 void OpenFileForIPC(const BrokerPolicy& policy, | 59 void OpenFileForIPC(const BrokerPolicy& policy, |
| 60 const std::string& requested_filename, | 60 const std::string& requested_filename, |
| 61 int flags, | 61 int flags, |
| 62 Pickle* write_pickle, | 62 base::Pickle* write_pickle, |
| 63 std::vector<int>* opened_files) { | 63 std::vector<int>* opened_files) { |
| 64 DCHECK(write_pickle); | 64 DCHECK(write_pickle); |
| 65 DCHECK(opened_files); | 65 DCHECK(opened_files); |
| 66 const char* file_to_open = NULL; | 66 const char* file_to_open = NULL; |
| 67 bool unlink_after_open = false; | 67 bool unlink_after_open = false; |
| 68 const bool safe_to_open_file = policy.GetFileNameIfAllowedToOpen( | 68 const bool safe_to_open_file = policy.GetFileNameIfAllowedToOpen( |
| 69 requested_filename.c_str(), flags, &file_to_open, &unlink_after_open); | 69 requested_filename.c_str(), flags, &file_to_open, &unlink_after_open); |
| 70 | 70 |
| 71 if (safe_to_open_file) { | 71 if (safe_to_open_file) { |
| 72 CHECK(file_to_open); | 72 CHECK(file_to_open); |
| (...skipping 11 matching lines...) Expand all Loading... |
| 84 } else { | 84 } else { |
| 85 write_pickle->WriteInt(-policy.denied_errno()); | 85 write_pickle->WriteInt(-policy.denied_errno()); |
| 86 } | 86 } |
| 87 } | 87 } |
| 88 | 88 |
| 89 // Perform access(2) on |requested_filename| with mode |mode| if allowed by our | 89 // Perform access(2) on |requested_filename| with mode |mode| if allowed by our |
| 90 // policy. Write the syscall return value (-errno) to |write_pickle|. | 90 // policy. Write the syscall return value (-errno) to |write_pickle|. |
| 91 void AccessFileForIPC(const BrokerPolicy& policy, | 91 void AccessFileForIPC(const BrokerPolicy& policy, |
| 92 const std::string& requested_filename, | 92 const std::string& requested_filename, |
| 93 int mode, | 93 int mode, |
| 94 Pickle* write_pickle) { | 94 base::Pickle* write_pickle) { |
| 95 DCHECK(write_pickle); | 95 DCHECK(write_pickle); |
| 96 const char* file_to_access = NULL; | 96 const char* file_to_access = NULL; |
| 97 const bool safe_to_access_file = policy.GetFileNameIfAllowedToAccess( | 97 const bool safe_to_access_file = policy.GetFileNameIfAllowedToAccess( |
| 98 requested_filename.c_str(), mode, &file_to_access); | 98 requested_filename.c_str(), mode, &file_to_access); |
| 99 | 99 |
| 100 if (safe_to_access_file) { | 100 if (safe_to_access_file) { |
| 101 CHECK(file_to_access); | 101 CHECK(file_to_access); |
| 102 int access_ret = access(file_to_access, mode); | 102 int access_ret = access(file_to_access, mode); |
| 103 int access_errno = errno; | 103 int access_errno = errno; |
| 104 if (!access_ret) | 104 if (!access_ret) |
| 105 write_pickle->WriteInt(0); | 105 write_pickle->WriteInt(0); |
| 106 else | 106 else |
| 107 write_pickle->WriteInt(-access_errno); | 107 write_pickle->WriteInt(-access_errno); |
| 108 } else { | 108 } else { |
| 109 write_pickle->WriteInt(-policy.denied_errno()); | 109 write_pickle->WriteInt(-policy.denied_errno()); |
| 110 } | 110 } |
| 111 } | 111 } |
| 112 | 112 |
| 113 // Handle a |command_type| request contained in |iter| and send the reply | 113 // Handle a |command_type| request contained in |iter| and send the reply |
| 114 // on |reply_ipc|. | 114 // on |reply_ipc|. |
| 115 // Currently COMMAND_OPEN and COMMAND_ACCESS are supported. | 115 // Currently COMMAND_OPEN and COMMAND_ACCESS are supported. |
| 116 bool HandleRemoteCommand(const BrokerPolicy& policy, | 116 bool HandleRemoteCommand(const BrokerPolicy& policy, |
| 117 IPCCommand command_type, | 117 IPCCommand command_type, |
| 118 int reply_ipc, | 118 int reply_ipc, |
| 119 PickleIterator iter) { | 119 base::PickleIterator iter) { |
| 120 // Currently all commands have two arguments: filename and flags. | 120 // Currently all commands have two arguments: filename and flags. |
| 121 std::string requested_filename; | 121 std::string requested_filename; |
| 122 int flags = 0; | 122 int flags = 0; |
| 123 if (!iter.ReadString(&requested_filename) || !iter.ReadInt(&flags)) | 123 if (!iter.ReadString(&requested_filename) || !iter.ReadInt(&flags)) |
| 124 return false; | 124 return false; |
| 125 | 125 |
| 126 Pickle write_pickle; | 126 base::Pickle write_pickle; |
| 127 std::vector<int> opened_files; | 127 std::vector<int> opened_files; |
| 128 | 128 |
| 129 switch (command_type) { | 129 switch (command_type) { |
| 130 case COMMAND_ACCESS: | 130 case COMMAND_ACCESS: |
| 131 AccessFileForIPC(policy, requested_filename, flags, &write_pickle); | 131 AccessFileForIPC(policy, requested_filename, flags, &write_pickle); |
| 132 break; | 132 break; |
| 133 case COMMAND_OPEN: | 133 case COMMAND_OPEN: |
| 134 OpenFileForIPC( | 134 OpenFileForIPC( |
| 135 policy, requested_filename, flags, &write_pickle, &opened_files); | 135 policy, requested_filename, flags, &write_pickle, &opened_files); |
| 136 break; | 136 break; |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 187 // The client should send exactly one file descriptor, on which we | 187 // The client should send exactly one file descriptor, on which we |
| 188 // will write the reply. | 188 // will write the reply. |
| 189 // TODO(mdempsky): ScopedVector doesn't have 'at()', only 'operator[]'. | 189 // TODO(mdempsky): ScopedVector doesn't have 'at()', only 'operator[]'. |
| 190 if (msg_len < 0 || fds.size() != 1 || fds[0]->get() < 0) { | 190 if (msg_len < 0 || fds.size() != 1 || fds[0]->get() < 0) { |
| 191 PLOG(ERROR) << "Error reading message from the client"; | 191 PLOG(ERROR) << "Error reading message from the client"; |
| 192 return RequestStatus::FAILURE; | 192 return RequestStatus::FAILURE; |
| 193 } | 193 } |
| 194 | 194 |
| 195 base::ScopedFD temporary_ipc(fds[0]->Pass()); | 195 base::ScopedFD temporary_ipc(fds[0]->Pass()); |
| 196 | 196 |
| 197 Pickle pickle(buf, msg_len); | 197 base::Pickle pickle(buf, msg_len); |
| 198 PickleIterator iter(pickle); | 198 base::PickleIterator iter(pickle); |
| 199 int command_type; | 199 int command_type; |
| 200 if (iter.ReadInt(&command_type)) { | 200 if (iter.ReadInt(&command_type)) { |
| 201 bool command_handled = false; | 201 bool command_handled = false; |
| 202 // Go through all the possible IPC messages. | 202 // Go through all the possible IPC messages. |
| 203 switch (command_type) { | 203 switch (command_type) { |
| 204 case COMMAND_ACCESS: | 204 case COMMAND_ACCESS: |
| 205 case COMMAND_OPEN: | 205 case COMMAND_OPEN: |
| 206 // We reply on the file descriptor sent to us via the IPC channel. | 206 // We reply on the file descriptor sent to us via the IPC channel. |
| 207 command_handled = HandleRemoteCommand( | 207 command_handled = HandleRemoteCommand( |
| 208 broker_policy_, static_cast<IPCCommand>(command_type), | 208 broker_policy_, static_cast<IPCCommand>(command_type), |
| (...skipping 13 matching lines...) Expand all Loading... |
| 222 NOTREACHED(); | 222 NOTREACHED(); |
| 223 } | 223 } |
| 224 | 224 |
| 225 LOG(ERROR) << "Error parsing IPC request"; | 225 LOG(ERROR) << "Error parsing IPC request"; |
| 226 return RequestStatus::FAILURE; | 226 return RequestStatus::FAILURE; |
| 227 } | 227 } |
| 228 | 228 |
| 229 } // namespace syscall_broker | 229 } // namespace syscall_broker |
| 230 | 230 |
| 231 } // namespace sandbox | 231 } // namespace sandbox |
| OLD | NEW |