diff options
author | jln@chromium.org <jln@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-26 00:34:54 +0000 |
---|---|---|
committer | jln@chromium.org <jln@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-04-26 00:34:54 +0000 |
commit | b09841583aae58d4bc8c244835915d964b044622 (patch) | |
tree | 659da6d253abb56efd12aba4c306e91349f11f89 /base/posix | |
parent | 7e7b513a69e603275434c1247b0d4897435ecf96 (diff) | |
download | chromium_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.cc | 26 | ||||
-rw-r--r-- | base/posix/unix_domain_socket_linux.h | 16 |
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_ |