summaryrefslogtreecommitdiffstats
path: root/ipc
diff options
context:
space:
mode:
authoragl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-06-10 21:39:04 +0000
committeragl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-06-10 21:39:04 +0000
commitaac449e7154720b895ff1e7f3497c2ce95ae1a5a (patch)
tree1964554316fe4b54cd0efa6ba471dd61467bfe39 /ipc
parentdc78796d35a53f758b2b6b729cf8a18034783d13 (diff)
downloadchromium_src-aac449e7154720b895ff1e7f3497c2ce95ae1a5a.zip
chromium_src-aac449e7154720b895ff1e7f3497c2ce95ae1a5a.tar.gz
chromium_src-aac449e7154720b895ff1e7f3497c2ce95ae1a5a.tar.bz2
POSIX: make sure that we never pass directory descriptors into the sandbox.
BUG=43304 http://codereview.chromium.org/2733011/show git-svn-id: svn://svn.chromium.org/chrome/trunk/src@49446 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ipc')
-rw-r--r--ipc/file_descriptor_set_posix.cc15
-rw-r--r--ipc/file_descriptor_set_posix.h3
-rw-r--r--ipc/ipc_channel_posix.cc9
3 files changed, 27 insertions, 0 deletions
diff --git a/ipc/file_descriptor_set_posix.cc b/ipc/file_descriptor_set_posix.cc
index 519e6e7..3796fae 100644
--- a/ipc/file_descriptor_set_posix.cc
+++ b/ipc/file_descriptor_set_posix.cc
@@ -4,6 +4,9 @@
#include "ipc/file_descriptor_set_posix.h"
+#include <sys/types.h>
+#include <sys/stat.h>
+
#include "base/eintr_wrapper.h"
#include "base/logging.h"
@@ -94,6 +97,18 @@ void FileDescriptorSet::GetDescriptors(int* buffer) const {
}
}
+bool FileDescriptorSet::ContainsDirectoryDescriptor() const {
+ struct stat st;
+
+ for (std::vector<base::FileDescriptor>::const_iterator
+ i = descriptors_.begin(); i != descriptors_.end(); ++i) {
+ if (fstat(i->fd, &st) == 0 && S_ISDIR(st.st_mode))
+ return true;
+ }
+
+ return false;
+}
+
void FileDescriptorSet::CommitAll() {
for (std::vector<base::FileDescriptor>::iterator
i = descriptors_.begin(); i != descriptors_.end(); ++i) {
diff --git a/ipc/file_descriptor_set_posix.h b/ipc/file_descriptor_set_posix.h
index 7653eb6..fcb5061 100644
--- a/ipc/file_descriptor_set_posix.h
+++ b/ipc/file_descriptor_set_posix.h
@@ -74,6 +74,9 @@ class FileDescriptorSet : public base::RefCountedThreadSafe<FileDescriptorSet> {
// GetDescriptors. It marks all the descriptors as consumed and closes those
// which are auto-close.
void CommitAll();
+ // Returns true if any contained file descriptors appear to be handles to a
+ // directory.
+ bool ContainsDirectoryDescriptor() const;
// ---------------------------------------------------------------------------
diff --git a/ipc/ipc_channel_posix.cc b/ipc/ipc_channel_posix.cc
index f4d6f7b..7c599ab 100644
--- a/ipc/ipc_channel_posix.cc
+++ b/ipc/ipc_channel_posix.cc
@@ -791,6 +791,15 @@ bool Channel::ChannelImpl::ProcessOutgoingMessages() {
const unsigned num_fds = msg->file_descriptor_set()->size();
DCHECK_LE(num_fds, FileDescriptorSet::MAX_DESCRIPTORS_PER_MESSAGE);
+ if (msg->file_descriptor_set()->ContainsDirectoryDescriptor()) {
+ LOG(FATAL) << "Panic: attempting to transport directory descriptor over"
+ " IPC. Aborting to maintain sandbox isolation.";
+ // If you have hit this then something tried to send a file descriptor
+ // to a directory over an IPC channel. Since IPC channels span
+ // sandboxes this is very bad: the receiving process can use openat
+ // with ".." elements in the path in order to reach the real
+ // filesystem.
+ }
msgh.msg_control = buf;
msgh.msg_controllen = CMSG_SPACE(sizeof(int) * num_fds);