summaryrefslogtreecommitdiffstats
path: root/ipc/ipc_channel_posix.cc
diff options
context:
space:
mode:
authorwez@chromium.org <wez@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-04-06 12:01:44 +0000
committerwez@chromium.org <wez@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-04-06 12:01:44 +0000
commit8ec3fbec285daa194f6397b998b4c4bc0c1b2a37 (patch)
tree8e0d6acc844cf4780ae36435f56bbef69d35c043 /ipc/ipc_channel_posix.cc
parentffc44870db7ad9b179b27644c497e813221888e0 (diff)
downloadchromium_src-8ec3fbec285daa194f6397b998b4c4bc0c1b2a37.zip
chromium_src-8ec3fbec285daa194f6397b998b4c4bc0c1b2a37.tar.gz
chromium_src-8ec3fbec285daa194f6397b998b4c4bc0c1b2a37.tar.bz2
Revert 80604 - Revert 80602 - Limit access to named IPC channels with SO_PEERCRED, not file permissions.BUG=TEST=Run Chrome & configure a service, to get the service process to start. Close Chrome and run a copy as a different user, but from the same user-data-dir. New Chrome should not be able to communicate with the service process.Review URL: http://codereview.chromium.org/6631002TBR=wez@chromium.orgReview URL: http://codereview.chromium.org/6806006
TBR=wez@chromium.org Review URL: http://codereview.chromium.org/6806007 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@80606 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'ipc/ipc_channel_posix.cc')
-rw-r--r--ipc/ipc_channel_posix.cc59
1 files changed, 46 insertions, 13 deletions
diff --git a/ipc/ipc_channel_posix.cc b/ipc/ipc_channel_posix.cc
index d9156d7..22e4781 100644
--- a/ipc/ipc_channel_posix.cc
+++ b/ipc/ipc_channel_posix.cc
@@ -193,19 +193,6 @@ bool CreateServerUnixDomainSocket(const std::string& pipe_name,
return false;
}
- // Explicitly set file system permissions on socket, mainly as a precaution
- // for Chrome OS.
- // Do not rely on these file permissions to provide security - the file is
- // created during the above bind() call so there is still a window for
- // malicious abuse because the file exists between bind() and chmod(). Also,
- // the file permissions may not be enforced for unix sockets on all platforms.
- if (chmod(pipe_name.c_str(), 0600)) {
- PLOG(ERROR) << "chmod " << pipe_name;
- if (HANDLE_EINTR(close(fd)) < 0)
- PLOG(ERROR) << "close " << pipe_name;
- return false;
- }
-
// Start listening on the socket.
const int listen_queue_length = 1;
if (listen(fd, listen_queue_length) != 0) {
@@ -938,6 +925,33 @@ bool Channel::ChannelImpl::HasAcceptedConnection() const {
return AcceptsConnections() && pipe_ != -1;
}
+bool Channel::ChannelImpl::GetClientEuid(uid_t* client_euid) const {
+ DCHECK(HasAcceptedConnection());
+#if defined(OS_MACOSX)
+ uid_t peer_euid;
+ gid_t peer_gid;
+ if (getpeereid(pipe_, &peer_euid, &peer_gid) != 0) {
+ PLOG(ERROR) << "getpeereid " << pipe_;
+ return false;
+ }
+ *client_euid = peer_euid;
+ return true;
+#else
+ struct ucred cred;
+ socklen_t cred_len = sizeof(cred);
+ if (getsockopt(pipe_, SOL_SOCKET, SO_PEERCRED, &cred, &cred_len) != 0) {
+ PLOG(ERROR) << "getsockopt " << pipe_;
+ return false;
+ }
+ if (cred_len < sizeof(cred)) {
+ NOTREACHED() << "Truncated ucred from SO_PEERCRED?";
+ return false;
+ }
+ *client_euid = cred.uid;
+ return true;
+#endif
+}
+
void Channel::ChannelImpl::ResetToAcceptingConnectionState() {
// Unregister libevent for the unix domain socket and close it.
read_watcher_.StopWatchingFileDescriptor();
@@ -997,6 +1011,21 @@ void Channel::ChannelImpl::OnFileCanReadWithoutBlocking(int fd) {
}
pipe_ = new_pipe;
+ if ((mode_ & MODE_OPEN_ACCESS_FLAG) == 0) {
+ // Verify that the IPC channel peer is running as the same user.
+ uid_t client_euid;
+ if (!GetClientEuid(&client_euid)) {
+ LOG(ERROR) << "Unable to query client euid";
+ ResetToAcceptingConnectionState();
+ return;
+ }
+ if (client_euid != geteuid()) {
+ LOG(WARNING) << "Client euid is not authorised";
+ ResetToAcceptingConnectionState();
+ return;
+ }
+ }
+
if (!AcceptConnection()) {
NOTREACHED() << "AcceptConnection should not fail on server";
}
@@ -1161,6 +1190,10 @@ bool Channel::HasAcceptedConnection() const {
return channel_impl_->HasAcceptedConnection();
}
+bool Channel::GetClientEuid(uid_t* client_euid) const {
+ return channel_impl_->GetClientEuid(client_euid);
+}
+
void Channel::ResetToAcceptingConnectionState() {
channel_impl_->ResetToAcceptingConnectionState();
}