diff options
author | agl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-06-10 21:39:04 +0000 |
---|---|---|
committer | agl@chromium.org <agl@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-06-10 21:39:04 +0000 |
commit | aac449e7154720b895ff1e7f3497c2ce95ae1a5a (patch) | |
tree | 1964554316fe4b54cd0efa6ba471dd61467bfe39 /ipc | |
parent | dc78796d35a53f758b2b6b729cf8a18034783d13 (diff) | |
download | chromium_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.cc | 15 | ||||
-rw-r--r-- | ipc/file_descriptor_set_posix.h | 3 | ||||
-rw-r--r-- | ipc/ipc_channel_posix.cc | 9 |
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); |