summaryrefslogtreecommitdiffstats
path: root/ipc
diff options
context:
space:
mode:
authorfischman@chromium.org <fischman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-04-09 21:40:44 +0000
committerfischman@chromium.org <fischman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-04-09 21:40:44 +0000
commit7e9eecb6b5a25ede2218e9efdae81d3bea6631e5 (patch)
treece135567fc472bc5cb50d88b9d574b242ec11820 /ipc
parent6866c6b33766ebbcb5af0217eda7c7c149a40251 (diff)
downloadchromium_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.cc9
-rw-r--r--ipc/ipc_channel_posix.h5
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_;