diff options
author | fischman@chromium.org <fischman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-04-09 21:40:44 +0000 |
---|---|---|
committer | fischman@chromium.org <fischman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-04-09 21:40:44 +0000 |
commit | 7e9eecb6b5a25ede2218e9efdae81d3bea6631e5 (patch) | |
tree | ce135567fc472bc5cb50d88b9d574b242ec11820 /ipc | |
parent | 6866c6b33766ebbcb5af0217eda7c7c149a40251 (diff) | |
download | chromium_src-7e9eecb6b5a25ede2218e9efdae81d3bea6631e5.zip chromium_src-7e9eecb6b5a25ede2218e9efdae81d3bea6631e5.tar.gz chromium_src-7e9eecb6b5a25ede2218e9efdae81d3bea6631e5.tar.bz2 |
Prevent reading invalid memory in IPC code caused by assumption of contiguity in std::deque<>.
std::vector<int> guarantees contiguous storage (as of C++2003, 23.2.4p1,
although in practice this is true with all known STL implementations), but
std::deque<> typically uses linked chains of array blocks, so specifically
*doesn't* provide contiguity once its size grows above its basic block size
(usually 512bytes on our linux systems).
BUG=117341
TEST=test in bug stops reproducing with this.
Review URL: http://codereview.chromium.org/10019018
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@131443 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ipc')
-rw-r--r-- | ipc/ipc_channel_posix.cc | 9 | ||||
-rw-r--r-- | ipc/ipc_channel_posix.h | 5 |
2 files changed, 10 insertions, 4 deletions
diff --git a/ipc/ipc_channel_posix.cc b/ipc/ipc_channel_posix.cc index 137aa5a..bb1aa05 100644 --- a/ipc/ipc_channel_posix.cc +++ b/ipc/ipc_channel_posix.cc @@ -1008,6 +1008,9 @@ bool Channel::ChannelImpl::WillDispatchInputMessage(Message* msg) { return false; } + // The shenaniganery below with &foo.front() requires input_fds_ to have + // contiguous underlying storage (such as a simple array or a std::vector). + // This is why the header warns not to make input_fds_ a deque<>. msg->file_descriptor_set()->SetDescriptors(&input_fds_.front(), header_fds); input_fds_.erase(input_fds_.begin(), input_fds_.begin() + header_fds); @@ -1054,11 +1057,11 @@ bool Channel::ChannelImpl::ExtractFileDescriptorsFromMsghdr(msghdr* msg) { } void Channel::ChannelImpl::ClearInputFDs() { - while (!input_fds_.empty()) { - if (HANDLE_EINTR(close(input_fds_.front())) < 0) + for (size_t i = 0; i < input_fds_.size(); ++i) { + if (HANDLE_EINTR(close(input_fds_[i])) < 0) PLOG(ERROR) << "close "; - input_fds_.pop_front(); } + input_fds_.clear(); } void Channel::ChannelImpl::HandleHelloMessage(const Message& msg) { diff --git a/ipc/ipc_channel_posix.h b/ipc/ipc_channel_posix.h index cb7eb84..c71370f 100644 --- a/ipc/ipc_channel_posix.h +++ b/ipc/ipc_channel_posix.h @@ -179,7 +179,10 @@ class Channel::ChannelImpl : public internal::ChannelReader, // File descriptors extracted from messages coming off of the channel. The // handles may span messages and come off different channels from the message // data (in the case of READWRITE), and are processed in FIFO here. - std::deque<int> input_fds_; + // NOTE: The implementation assumes underlying storage here is contiguous, so + // don't change to something like std::deque<> without changing the + // implementation! + std::vector<int> input_fds_; // True if we are responsible for unlinking the unix domain socket file. bool must_unlink_; |