diff options
author | jamescook@chromium.org <jamescook@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-08-31 21:11:04 +0000 |
---|---|---|
committer | jamescook@chromium.org <jamescook@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-08-31 21:11:04 +0000 |
commit | e1d67a8826a4a19e370b8f9f18b45bff4d4de163 (patch) | |
tree | 986b2ec88dc7a312435bb307e648daeac401a648 /ipc | |
parent | 943b86100cc75e6fbccdf82aeca23cce9aa66508 (diff) | |
download | chromium_src-e1d67a8826a4a19e370b8f9f18b45bff4d4de163.zip chromium_src-e1d67a8826a4a19e370b8f9f18b45bff4d4de163.tar.gz chromium_src-e1d67a8826a4a19e370b8f9f18b45bff4d4de163.tar.bz2 |
Fix IPC OnChannelConnected() to send correct PID on Linux/CrOS
Sandboxed renderers on Linux/CrOS are in a PID namespace, so they don't know
their own global PID. Thus the PID sent in the IPC channel Hello message
contains an unexpected value, which is used in the OnChannelConnected()
callback into chrome.
This causes problems like the Task Manager not showing any data for FPS,
JavaScript memory and image cache memory. The task manager is attempting to
use the PID/process handle from BrowserMessageFilter, which got it from
IPC::Channel::Listener::OnChannelConnected(), and it doesn't match the
global PID of each renderer.
BUG=70179
TEST=manual, open a few tabs, then open task manager, right-click to turn on JavaScript memory and image memory. Verify there are non-zero values for FPS, JavaScript memory, image cache memory
Review URL: http://codereview.chromium.org/7778031
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@99040 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ipc')
-rw-r--r-- | ipc/ipc_channel.h | 7 | ||||
-rw-r--r-- | ipc/ipc_channel_posix.cc | 32 | ||||
-rw-r--r-- | ipc/ipc_channel_posix.h | 9 |
3 files changed, 46 insertions, 2 deletions
diff --git a/ipc/ipc_channel.h b/ipc/ipc_channel.h index cd57b4b..3724e56 100644 --- a/ipc/ipc_channel.h +++ b/ipc/ipc_channel.h @@ -175,6 +175,13 @@ class IPC_EXPORT Channel : public Message::Sender { // ID. Even if true, the server may have already accepted a connection. static bool IsNamedServerInitialized(const std::string& channel_id); +#if defined(OS_LINUX) + // Sandboxed processes live in a PID namespace, so when sending the IPC hello + // message from client to server we need to send the PID from the global + // PID namespace. + static void SetGlobalPid(int pid); +#endif + protected: // Used in Chrome by the TestSink to provide a dummy channel implementation // for testing. TestSink overrides the "interesting" functions in Channel so diff --git a/ipc/ipc_channel_posix.cc b/ipc/ipc_channel_posix.cc index 8cda88b..df927d0 100644 --- a/ipc/ipc_channel_posix.cc +++ b/ipc/ipc_channel_posix.cc @@ -293,6 +293,10 @@ bool SocketWriteErrorIsRecoverable() { } // namespace //------------------------------------------------------------------------------ +#if defined(OS_LINUX) +int Channel::ChannelImpl::global_pid_ = 0; +#endif // OS_LINUX + Channel::ChannelImpl::ChannelImpl(const IPC::ChannelHandle& channel_handle, Mode mode, Listener* listener) : mode_(mode), @@ -997,6 +1001,13 @@ bool Channel::ChannelImpl::IsNamedServerInitialized( return file_util::PathExists(FilePath(channel_id)); } +#if defined(OS_LINUX) +// static +void Channel::ChannelImpl::SetGlobalPid(int pid) { + global_pid_ = pid; +} +#endif // OS_LINUX + // Called by libevent when we can read from the pipe without blocking. void Channel::ChannelImpl::OnFileCanReadWithoutBlocking(int fd) { bool send_server_hello_msg = false; @@ -1109,13 +1120,23 @@ void Channel::ChannelImpl::ClosePipeOnError() { } } +int Channel::ChannelImpl::GetHelloMessageProcId() { + int pid = base::GetCurrentProcId(); +#if defined(OS_LINUX) + // Our process may be in a sandbox with a separate PID namespace. + if (global_pid_) { + pid = global_pid_; + } +#endif + return pid; +} + void Channel::ChannelImpl::QueueHelloMessage() { // Create the Hello message scoped_ptr<Message> msg(new Message(MSG_ROUTING_NONE, HELLO_MESSAGE_TYPE, IPC::Message::PRIORITY_NORMAL)); - - if (!msg->WriteInt(base::GetCurrentProcId())) { + if (!msg->WriteInt(GetHelloMessageProcId())) { NOTREACHED() << "Unable to pickle hello message proc id"; } #if defined(IPC_USES_READWRITE) @@ -1211,4 +1232,11 @@ bool Channel::IsNamedServerInitialized(const std::string& channel_id) { return ChannelImpl::IsNamedServerInitialized(channel_id); } +#if defined(OS_LINUX) +// static +void Channel::SetGlobalPid(int pid) { + ChannelImpl::SetGlobalPid(pid); +} +#endif // OS_LINUX + } // namespace IPC diff --git a/ipc/ipc_channel_posix.h b/ipc/ipc_channel_posix.h index b66b1fc..399d282 100644 --- a/ipc/ipc_channel_posix.h +++ b/ipc/ipc_channel_posix.h @@ -63,6 +63,9 @@ class Channel::ChannelImpl : public MessageLoopForIO::Watcher { bool GetClientEuid(uid_t* client_euid) const; void ResetToAcceptingConnectionState(); static bool IsNamedServerInitialized(const std::string& channel_id); +#if defined(OS_LINUX) + static void SetGlobalPid(int pid); +#endif // OS_LINUX private: bool CreatePipe(const IPC::ChannelHandle& channel_handle); @@ -72,6 +75,7 @@ class Channel::ChannelImpl : public MessageLoopForIO::Watcher { bool AcceptConnection(); void ClosePipeOnError(); + int GetHelloMessageProcId(); void QueueHelloMessage(); bool IsHelloMessage(const Message* m) const; @@ -147,6 +151,11 @@ class Channel::ChannelImpl : public MessageLoopForIO::Watcher { // True if we are responsible for unlinking the unix domain socket file. bool must_unlink_; +#if defined(OS_LINUX) + // If non-zero, overrides the process ID sent in the hello message. + static int global_pid_; +#endif // OS_LINUX + DISALLOW_IMPLICIT_CONSTRUCTORS(ChannelImpl); }; |