summaryrefslogtreecommitdiffstats
path: root/base/posix
diff options
context:
space:
mode:
authorjln@chromium.org <jln@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-04-26 00:34:54 +0000
committerjln@chromium.org <jln@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-04-26 00:34:54 +0000
commitb09841583aae58d4bc8c244835915d964b044622 (patch)
tree659da6d253abb56efd12aba4c306e91349f11f89 /base/posix
parent7e7b513a69e603275434c1247b0d4897435ecf96 (diff)
downloadchromium_src-b09841583aae58d4bc8c244835915d964b044622.zip
chromium_src-b09841583aae58d4bc8c244835915d964b044622.tar.gz
chromium_src-b09841583aae58d4bc8c244835915d964b044622.tar.bz2
Linux sandbox: allow non racy use of O_CLOEXEC
The current support of O_CLOEXEC in Open() in the broker process is racy. We make it non racy by using MSG_CMSG_CLOEXEC in recvmsg when getting the new file descriptor over the Unix socket. BUG=232077, 232068 NOTRY=true Review URL: https://chromiumcodereview.appspot.com/14407005 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@196554 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'base/posix')
-rw-r--r--base/posix/unix_domain_socket_linux.cc26
-rw-r--r--base/posix/unix_domain_socket_linux.h16
2 files changed, 40 insertions, 2 deletions
diff --git a/base/posix/unix_domain_socket_linux.cc b/base/posix/unix_domain_socket_linux.cc
index 603459f..757db98 100644
--- a/base/posix/unix_domain_socket_linux.cc
+++ b/base/posix/unix_domain_socket_linux.cc
@@ -58,6 +58,15 @@ ssize_t UnixDomainSocket::RecvMsg(int fd,
void* buf,
size_t length,
std::vector<int>* fds) {
+ return UnixDomainSocket::RecvMsgWithFlags(fd, buf, length, 0, fds);
+}
+
+// static
+ssize_t UnixDomainSocket::RecvMsgWithFlags(int fd,
+ void* buf,
+ size_t length,
+ int flags,
+ std::vector<int>* fds) {
fds->clear();
struct msghdr msg = {};
@@ -69,7 +78,7 @@ ssize_t UnixDomainSocket::RecvMsg(int fd,
msg.msg_control = control_buffer;
msg.msg_controllen = sizeof(control_buffer);
- const ssize_t r = HANDLE_EINTR(recvmsg(fd, &msg, 0));
+ const ssize_t r = HANDLE_EINTR(recvmsg(fd, &msg, flags));
if (r == -1)
return -1;
@@ -109,6 +118,18 @@ ssize_t UnixDomainSocket::SendRecvMsg(int fd,
unsigned max_reply_len,
int* result_fd,
const Pickle& request) {
+ return UnixDomainSocket::SendRecvMsgWithFlags(fd, reply, max_reply_len,
+ 0, /* recvmsg_flags */
+ result_fd, request);
+}
+
+// static
+ssize_t UnixDomainSocket::SendRecvMsgWithFlags(int fd,
+ uint8_t* reply,
+ unsigned max_reply_len,
+ int recvmsg_flags,
+ int* result_fd,
+ const Pickle& request) {
int fds[2];
// This socketpair is only used for the IPC and is cleaned up before
@@ -128,7 +149,8 @@ ssize_t UnixDomainSocket::SendRecvMsg(int fd,
fd_vector.clear();
// When porting to OSX keep in mind it doesn't support MSG_NOSIGNAL, so the
// sender might get a SIGPIPE.
- const ssize_t reply_len = RecvMsg(fds[0], reply, max_reply_len, &fd_vector);
+ const ssize_t reply_len = RecvMsgWithFlags(fds[0], reply, max_reply_len,
+ recvmsg_flags, &fd_vector);
close(fds[0]);
if (reply_len == -1)
return -1;
diff --git a/base/posix/unix_domain_socket_linux.h b/base/posix/unix_domain_socket_linux.h
index b8ba460..66fb8bb 100644
--- a/base/posix/unix_domain_socket_linux.h
+++ b/base/posix/unix_domain_socket_linux.h
@@ -55,6 +55,22 @@ class BASE_EXPORT UnixDomainSocket {
unsigned reply_len,
int* result_fd,
const Pickle& request);
+
+ // Similar to SendRecvMsg(), but |recvmsg_flags| allows to control the flags
+ // of the recvmsg(2) call.
+ static ssize_t SendRecvMsgWithFlags(int fd,
+ uint8_t* reply,
+ unsigned reply_len,
+ int recvmsg_flags,
+ int* result_fd,
+ const Pickle& request);
+ private:
+ // Similar to RecvMsg, but allows to specify |flags| for recvmsg(2).
+ static ssize_t RecvMsgWithFlags(int fd,
+ void* msg,
+ size_t length,
+ int flags,
+ std::vector<int>* fds);
};
#endif // BASE_POSIX_UNIX_DOMAIN_SOCKET_LINUX_H_