Avi Drissman | e4622aa | 2022-09-08 20:36:06 | [diff] [blame] | 1 | // Copyright 2011 The Chromium Authors |
[email protected] | cc8f146 | 2009-06-12 17:36:55 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
| 4 | |
danakj | 51d26a4 | 2024-04-25 14:23:56 | [diff] [blame] | 5 | #ifdef UNSAFE_BUFFERS_BUILD |
| 6 | // TODO(crbug.com/40284755): Remove this and spanify to fix the errors. |
| 7 | #pragma allow_unsafe_buffers |
| 8 | #endif |
| 9 | |
Boris Vidolov | 8ecb49e | 2017-07-26 06:35:46 | [diff] [blame] | 10 | #include "base/posix/unix_domain_socket.h" |
[email protected] | cc8f146 | 2009-06-12 17:36:55 | [diff] [blame] | 11 | |
[email protected] | f884f2a | 2010-02-02 01:24:49 | [diff] [blame] | 12 | #include <errno.h> |
[email protected] | cc8f146 | 2009-06-12 17:36:55 | [diff] [blame] | 13 | #include <sys/socket.h> |
Nico Weber | 2388b39 | 2021-12-09 00:15:25 | [diff] [blame] | 14 | #include <sys/uio.h> |
Boris Vidolov | 8ecb49e | 2017-07-26 06:35:46 | [diff] [blame] | 15 | #include <sys/un.h> |
[email protected] | 8c89c59 | 2013-01-18 10:34:29 | [diff] [blame] | 16 | #include <unistd.h> |
[email protected] | cc8f146 | 2009-06-12 17:36:55 | [diff] [blame] | 17 | |
[email protected] | 8feaa67 | 2014-04-30 21:57:10 | [diff] [blame] | 18 | #include <vector> |
| 19 | |
| 20 | #include "base/files/scoped_file.h" |
[email protected] | cc8f146 | 2009-06-12 17:36:55 | [diff] [blame] | 21 | #include "base/logging.h" |
Hans Wennborg | afeb390 | 2020-06-17 14:42:29 | [diff] [blame] | 22 | #include "base/notreached.h" |
Peter Kasting | b7445486 | 2022-07-13 00:40:12 | [diff] [blame] | 23 | #include "base/numerics/safe_conversions.h" |
[email protected] | 43235a0 | 2009-06-18 00:44:42 | [diff] [blame] | 24 | #include "base/pickle.h" |
[email protected] | 2025d00 | 2012-11-14 20:54:35 | [diff] [blame] | 25 | #include "base/posix/eintr_wrapper.h" |
avi | 9b6f4293 | 2015-12-26 22:15:14 | [diff] [blame] | 26 | #include "build/build_config.h" |
[email protected] | cc8f146 | 2009-06-12 17:36:55 | [diff] [blame] | 27 | |
brettw | a027ae3 | 2015-06-02 19:48:29 | [diff] [blame] | 28 | namespace base { |
| 29 | |
[email protected] | 375a846 | 2012-10-12 19:59:39 | [diff] [blame] | 30 | const size_t UnixDomainSocket::kMaxFileDescriptors = 16; |
| 31 | |
shunhsingou | 6a52479 | 2017-04-06 04:17:06 | [diff] [blame] | 32 | bool CreateSocketPair(ScopedFD* one, ScopedFD* two) { |
[email protected] | 8feaa67 | 2014-04-30 21:57:10 | [diff] [blame] | 33 | int raw_socks[2]; |
Xiaohan Wang | 1a8409ee | 2022-01-15 14:56:41 | [diff] [blame] | 34 | #if BUILDFLAG(IS_APPLE) |
Boris Vidolov | 8ecb49e | 2017-07-26 06:35:46 | [diff] [blame] | 35 | // macOS does not support SEQPACKET. |
| 36 | const int flags = SOCK_STREAM; |
| 37 | #else |
| 38 | const int flags = SOCK_SEQPACKET; |
| 39 | #endif |
Peter Kasting | 134ef9af | 2024-12-28 02:30:09 | [diff] [blame] | 40 | if (socketpair(AF_UNIX, flags, 0, raw_socks) == -1) { |
[email protected] | 8feaa67 | 2014-04-30 21:57:10 | [diff] [blame] | 41 | return false; |
Peter Kasting | 134ef9af | 2024-12-28 02:30:09 | [diff] [blame] | 42 | } |
[email protected] | 8feaa67 | 2014-04-30 21:57:10 | [diff] [blame] | 43 | one->reset(raw_socks[0]); |
| 44 | two->reset(raw_socks[1]); |
| 45 | return true; |
| 46 | } |
| 47 | |
[email protected] | cf3ac397 | 2010-12-22 20:02:29 | [diff] [blame] | 48 | // static |
[email protected] | 1dc3796b | 2014-04-24 23:42:42 | [diff] [blame] | 49 | bool UnixDomainSocket::EnableReceiveProcessId(int fd) { |
Xiaohan Wang | 1a8409ee | 2022-01-15 14:56:41 | [diff] [blame] | 50 | #if !BUILDFLAG(IS_APPLE) |
[email protected] | 1dc3796b | 2014-04-24 23:42:42 | [diff] [blame] | 51 | const int enable = 1; |
| 52 | return setsockopt(fd, SOL_SOCKET, SO_PASSCRED, &enable, sizeof(enable)) == 0; |
Boris Vidolov | 8ecb49e | 2017-07-26 06:35:46 | [diff] [blame] | 53 | #else |
| 54 | // SO_PASSCRED is not supported on macOS. |
| 55 | return true; |
Xiaohan Wang | 1a8409ee | 2022-01-15 14:56:41 | [diff] [blame] | 56 | #endif // BUILDFLAG(IS_APPLE) |
[email protected] | 1dc3796b | 2014-04-24 23:42:42 | [diff] [blame] | 57 | } |
| 58 | |
| 59 | // static |
[email protected] | cf3ac397 | 2010-12-22 20:02:29 | [diff] [blame] | 60 | bool UnixDomainSocket::SendMsg(int fd, |
| 61 | const void* buf, |
| 62 | size_t length, |
| 63 | const std::vector<int>& fds) { |
[email protected] | 8c89c59 | 2013-01-18 10:34:29 | [diff] [blame] | 64 | struct msghdr msg = {}; |
Boris Vidolov | 8ecb49e | 2017-07-26 06:35:46 | [diff] [blame] | 65 | struct iovec iov = {const_cast<void*>(buf), length}; |
[email protected] | cc8f146 | 2009-06-12 17:36:55 | [diff] [blame] | 66 | msg.msg_iov = &iov; |
| 67 | msg.msg_iovlen = 1; |
| 68 | |
Ivan Kotenkov | a16212a5 | 2017-11-08 12:37:33 | [diff] [blame] | 69 | char* control_buffer = nullptr; |
[email protected] | cc8f146 | 2009-06-12 17:36:55 | [diff] [blame] | 70 | if (fds.size()) { |
Peter Kasting | 0aa382f6 | 2022-07-05 15:57:07 | [diff] [blame] | 71 | const size_t control_len = CMSG_SPACE(sizeof(int) * fds.size()); |
[email protected] | cc8f146 | 2009-06-12 17:36:55 | [diff] [blame] | 72 | control_buffer = new char[control_len]; |
[email protected] | cc8f146 | 2009-06-12 17:36:55 | [diff] [blame] | 73 | |
[email protected] | 8c89c59 | 2013-01-18 10:34:29 | [diff] [blame] | 74 | struct cmsghdr* cmsg; |
[email protected] | cc8f146 | 2009-06-12 17:36:55 | [diff] [blame] | 75 | msg.msg_control = control_buffer; |
Peter Kasting | 2f61c8b | 2022-07-19 23:43:46 | [diff] [blame] | 76 | #if BUILDFLAG(IS_APPLE) |
Peter Kasting | b7445486 | 2022-07-13 00:40:12 | [diff] [blame] | 77 | msg.msg_controllen = checked_cast<socklen_t>(control_len); |
Peter Kasting | 2f61c8b | 2022-07-19 23:43:46 | [diff] [blame] | 78 | #else |
| 79 | msg.msg_controllen = control_len; |
| 80 | #endif |
[email protected] | cc8f146 | 2009-06-12 17:36:55 | [diff] [blame] | 81 | cmsg = CMSG_FIRSTHDR(&msg); |
| 82 | cmsg->cmsg_level = SOL_SOCKET; |
| 83 | cmsg->cmsg_type = SCM_RIGHTS; |
Peter Kasting | 2f61c8b | 2022-07-19 23:43:46 | [diff] [blame] | 84 | #if BUILDFLAG(IS_APPLE) |
| 85 | cmsg->cmsg_len = checked_cast<u_int>(CMSG_LEN(sizeof(int) * fds.size())); |
| 86 | #else |
| 87 | cmsg->cmsg_len = CMSG_LEN(sizeof(int) * fds.size()); |
| 88 | #endif |
[email protected] | cc8f146 | 2009-06-12 17:36:55 | [diff] [blame] | 89 | memcpy(CMSG_DATA(cmsg), &fds[0], sizeof(int) * fds.size()); |
| 90 | msg.msg_controllen = cmsg->cmsg_len; |
| 91 | } |
| 92 | |
Nico Weber | b8da41e2 | 2024-11-25 20:51:32 | [diff] [blame] | 93 | // Avoid a SIGPIPE if the other end breaks the connection. |
| 94 | // Due to a bug in the Linux kernel (net/unix/af_unix.c) MSG_NOSIGNAL isn't |
| 95 | // regarded for SOCK_SEQPACKET in the AF_UNIX domain, but it is mandated by |
| 96 | // POSIX. |
| 97 | const ssize_t r = HANDLE_EINTR(sendmsg(fd, &msg, MSG_NOSIGNAL)); |
[email protected] | cc8f146 | 2009-06-12 17:36:55 | [diff] [blame] | 98 | const bool ret = static_cast<ssize_t>(length) == r; |
| 99 | delete[] control_buffer; |
| 100 | return ret; |
| 101 | } |
| 102 | |
[email protected] | cf3ac397 | 2010-12-22 20:02:29 | [diff] [blame] | 103 | // static |
| 104 | ssize_t UnixDomainSocket::RecvMsg(int fd, |
| 105 | void* buf, |
| 106 | size_t length, |
mdempsky | f12295a | 2015-12-09 22:54:46 | [diff] [blame] | 107 | std::vector<ScopedFD>* fds) { |
Ivan Kotenkov | a16212a5 | 2017-11-08 12:37:33 | [diff] [blame] | 108 | return UnixDomainSocket::RecvMsgWithPid(fd, buf, length, fds, nullptr); |
[email protected] | 1dc3796b | 2014-04-24 23:42:42 | [diff] [blame] | 109 | } |
| 110 | |
| 111 | // static |
| 112 | ssize_t UnixDomainSocket::RecvMsgWithPid(int fd, |
| 113 | void* buf, |
| 114 | size_t length, |
mdempsky | f12295a | 2015-12-09 22:54:46 | [diff] [blame] | 115 | std::vector<ScopedFD>* fds, |
brettw | a027ae3 | 2015-06-02 19:48:29 | [diff] [blame] | 116 | ProcessId* pid) { |
[email protected] | 1dc3796b | 2014-04-24 23:42:42 | [diff] [blame] | 117 | return UnixDomainSocket::RecvMsgWithFlags(fd, buf, length, 0, fds, pid); |
[email protected] | b098415 | 2013-04-26 00:34:54 | [diff] [blame] | 118 | } |
| 119 | |
| 120 | // static |
| 121 | ssize_t UnixDomainSocket::RecvMsgWithFlags(int fd, |
| 122 | void* buf, |
| 123 | size_t length, |
| 124 | int flags, |
mdempsky | f12295a | 2015-12-09 22:54:46 | [diff] [blame] | 125 | std::vector<ScopedFD>* fds, |
brettw | a027ae3 | 2015-06-02 19:48:29 | [diff] [blame] | 126 | ProcessId* out_pid) { |
[email protected] | cc8f146 | 2009-06-12 17:36:55 | [diff] [blame] | 127 | fds->clear(); |
| 128 | |
[email protected] | 8c89c59 | 2013-01-18 10:34:29 | [diff] [blame] | 129 | struct msghdr msg = {}; |
Boris Vidolov | 8ecb49e | 2017-07-26 06:35:46 | [diff] [blame] | 130 | struct iovec iov = {buf, length}; |
[email protected] | cc8f146 | 2009-06-12 17:36:55 | [diff] [blame] | 131 | msg.msg_iov = &iov; |
| 132 | msg.msg_iovlen = 1; |
| 133 | |
hidehiko | 2b720d2 | 2014-10-17 06:40:30 | [diff] [blame] | 134 | const size_t kControlBufferSize = |
| 135 | CMSG_SPACE(sizeof(int) * kMaxFileDescriptors) |
Xiaohan Wang | 1a8409ee | 2022-01-15 14:56:41 | [diff] [blame] | 136 | #if !BUILDFLAG(IS_APPLE) |
Nico Weber | 2388b39 | 2021-12-09 00:15:25 | [diff] [blame] | 137 | // macOS does not support ucred. |
| 138 | // macOS supports xucred, but this structure is insufficient. |
hidehiko | 2b720d2 | 2014-10-17 06:40:30 | [diff] [blame] | 139 | + CMSG_SPACE(sizeof(struct ucred)) |
Xiaohan Wang | 1a8409ee | 2022-01-15 14:56:41 | [diff] [blame] | 140 | #endif // !BUILDFLAG(IS_APPLE) |
hidehiko | 2b720d2 | 2014-10-17 06:40:30 | [diff] [blame] | 141 | ; |
| 142 | char control_buffer[kControlBufferSize]; |
[email protected] | cc8f146 | 2009-06-12 17:36:55 | [diff] [blame] | 143 | msg.msg_control = control_buffer; |
| 144 | msg.msg_controllen = sizeof(control_buffer); |
| 145 | |
[email protected] | b098415 | 2013-04-26 00:34:54 | [diff] [blame] | 146 | const ssize_t r = HANDLE_EINTR(recvmsg(fd, &msg, flags)); |
Peter Kasting | 134ef9af | 2024-12-28 02:30:09 | [diff] [blame] | 147 | if (r == -1) { |
[email protected] | cc8f146 | 2009-06-12 17:36:55 | [diff] [blame] | 148 | return -1; |
Peter Kasting | 134ef9af | 2024-12-28 02:30:09 | [diff] [blame] | 149 | } |
[email protected] | cc8f146 | 2009-06-12 17:36:55 | [diff] [blame] | 150 | |
Ivan Kotenkov | a16212a5 | 2017-11-08 12:37:33 | [diff] [blame] | 151 | int* wire_fds = nullptr; |
Peter Kasting | 0aa382f6 | 2022-07-05 15:57:07 | [diff] [blame] | 152 | size_t wire_fds_len = 0; |
brettw | a027ae3 | 2015-06-02 19:48:29 | [diff] [blame] | 153 | ProcessId pid = -1; |
[email protected] | cc8f146 | 2009-06-12 17:36:55 | [diff] [blame] | 154 | |
| 155 | if (msg.msg_controllen > 0) { |
| 156 | struct cmsghdr* cmsg; |
| 157 | for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) { |
Peter Kasting | 0aa382f6 | 2022-07-05 15:57:07 | [diff] [blame] | 158 | const size_t payload_len = cmsg->cmsg_len - CMSG_LEN(0); |
Boris Vidolov | 8ecb49e | 2017-07-26 06:35:46 | [diff] [blame] | 159 | if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) { |
danakj | 94219a21 | 2015-03-09 22:27:25 | [diff] [blame] | 160 | DCHECK_EQ(payload_len % sizeof(int), 0u); |
| 161 | DCHECK_EQ(wire_fds, static_cast<void*>(nullptr)); |
[email protected] | cc8f146 | 2009-06-12 17:36:55 | [diff] [blame] | 162 | wire_fds = reinterpret_cast<int*>(CMSG_DATA(cmsg)); |
| 163 | wire_fds_len = payload_len / sizeof(int); |
[email protected] | 1dc3796b | 2014-04-24 23:42:42 | [diff] [blame] | 164 | } |
Xiaohan Wang | 1a8409ee | 2022-01-15 14:56:41 | [diff] [blame] | 165 | #if !BUILDFLAG(IS_APPLE) |
Nico Weber | 2388b39 | 2021-12-09 00:15:25 | [diff] [blame] | 166 | // macOS does not support SCM_CREDENTIALS. |
[email protected] | 1dc3796b | 2014-04-24 23:42:42 | [diff] [blame] | 167 | if (cmsg->cmsg_level == SOL_SOCKET && |
| 168 | cmsg->cmsg_type == SCM_CREDENTIALS) { |
danakj | 94219a21 | 2015-03-09 22:27:25 | [diff] [blame] | 169 | DCHECK_EQ(payload_len, sizeof(struct ucred)); |
| 170 | DCHECK_EQ(pid, -1); |
[email protected] | 1dc3796b | 2014-04-24 23:42:42 | [diff] [blame] | 171 | pid = reinterpret_cast<struct ucred*>(CMSG_DATA(cmsg))->pid; |
[email protected] | cc8f146 | 2009-06-12 17:36:55 | [diff] [blame] | 172 | } |
Xiaohan Wang | 1a8409ee | 2022-01-15 14:56:41 | [diff] [blame] | 173 | #endif // !BUILDFLAG(IS_APPLE) |
[email protected] | cc8f146 | 2009-06-12 17:36:55 | [diff] [blame] | 174 | } |
| 175 | } |
| 176 | |
| 177 | if (msg.msg_flags & MSG_TRUNC || msg.msg_flags & MSG_CTRUNC) { |
Harald Alvestrand | 67def1f | 2018-04-12 11:33:58 | [diff] [blame] | 178 | if (msg.msg_flags & MSG_CTRUNC) { |
| 179 | // Extraordinary case, not caller fixable. Log something. |
| 180 | LOG(ERROR) << "recvmsg returned MSG_CTRUNC flag, buffer len is " |
| 181 | << msg.msg_controllen; |
| 182 | } |
Peter Kasting | 134ef9af | 2024-12-28 02:30:09 | [diff] [blame] | 183 | for (size_t i = 0; i < wire_fds_len; ++i) { |
[email protected] | cc8f146 | 2009-06-12 17:36:55 | [diff] [blame] | 184 | close(wire_fds[i]); |
Peter Kasting | 134ef9af | 2024-12-28 02:30:09 | [diff] [blame] | 185 | } |
[email protected] | cc8f146 | 2009-06-12 17:36:55 | [diff] [blame] | 186 | errno = EMSGSIZE; |
| 187 | return -1; |
| 188 | } |
| 189 | |
[email protected] | a4a5580 | 2014-03-17 22:00:24 | [diff] [blame] | 190 | if (wire_fds) { |
Peter Kasting | 134ef9af | 2024-12-28 02:30:09 | [diff] [blame] | 191 | for (size_t i = 0; i < wire_fds_len; ++i) { |
Peter Kasting | 811504a7 | 2025-01-09 03:18:50 | [diff] [blame] | 192 | fds->emplace_back(wire_fds[i]); |
Peter Kasting | 134ef9af | 2024-12-28 02:30:09 | [diff] [blame] | 193 | } |
[email protected] | a4a5580 | 2014-03-17 22:00:24 | [diff] [blame] | 194 | } |
[email protected] | cc8f146 | 2009-06-12 17:36:55 | [diff] [blame] | 195 | |
[email protected] | 1dc3796b | 2014-04-24 23:42:42 | [diff] [blame] | 196 | if (out_pid) { |
Xiaohan Wang | 1a8409ee | 2022-01-15 14:56:41 | [diff] [blame] | 197 | #if BUILDFLAG(IS_APPLE) |
Boris Vidolov | 8ecb49e | 2017-07-26 06:35:46 | [diff] [blame] | 198 | socklen_t pid_size = sizeof(pid); |
Peter Kasting | 134ef9af | 2024-12-28 02:30:09 | [diff] [blame] | 199 | if (getsockopt(fd, SOL_LOCAL, LOCAL_PEERPID, &pid, &pid_size) != 0) { |
Boris Vidolov | 8ecb49e | 2017-07-26 06:35:46 | [diff] [blame] | 200 | pid = -1; |
Peter Kasting | 134ef9af | 2024-12-28 02:30:09 | [diff] [blame] | 201 | } |
Boris Vidolov | 8ecb49e | 2017-07-26 06:35:46 | [diff] [blame] | 202 | #else |
[email protected] | d438013 | 2014-05-16 08:57:55 | [diff] [blame] | 203 | // |pid| will legitimately be -1 if we read EOF, so only DCHECK if we |
| 204 | // actually received a message. Unfortunately, Linux allows sending zero |
| 205 | // length messages, which are indistinguishable from EOF, so this check |
| 206 | // has false negatives. |
Peter Kasting | 134ef9af | 2024-12-28 02:30:09 | [diff] [blame] | 207 | if (r > 0 || msg.msg_controllen > 0) { |
[email protected] | d438013 | 2014-05-16 08:57:55 | [diff] [blame] | 208 | DCHECK_GE(pid, 0); |
Peter Kasting | 134ef9af | 2024-12-28 02:30:09 | [diff] [blame] | 209 | } |
Boris Vidolov | 8ecb49e | 2017-07-26 06:35:46 | [diff] [blame] | 210 | #endif |
[email protected] | d438013 | 2014-05-16 08:57:55 | [diff] [blame] | 211 | |
[email protected] | 1dc3796b | 2014-04-24 23:42:42 | [diff] [blame] | 212 | *out_pid = pid; |
| 213 | } |
| 214 | |
[email protected] | cc8f146 | 2009-06-12 17:36:55 | [diff] [blame] | 215 | return r; |
| 216 | } |
| 217 | |
[email protected] | cf3ac397 | 2010-12-22 20:02:29 | [diff] [blame] | 218 | // static |
| 219 | ssize_t UnixDomainSocket::SendRecvMsg(int fd, |
| 220 | uint8_t* reply, |
| 221 | unsigned max_reply_len, |
| 222 | int* result_fd, |
| 223 | const Pickle& request) { |
[email protected] | b098415 | 2013-04-26 00:34:54 | [diff] [blame] | 224 | return UnixDomainSocket::SendRecvMsgWithFlags(fd, reply, max_reply_len, |
Boris Vidolov | 8ecb49e | 2017-07-26 06:35:46 | [diff] [blame] | 225 | 0, /* recvmsg_flags */ |
[email protected] | b098415 | 2013-04-26 00:34:54 | [diff] [blame] | 226 | result_fd, request); |
| 227 | } |
| 228 | |
| 229 | // static |
| 230 | ssize_t UnixDomainSocket::SendRecvMsgWithFlags(int fd, |
| 231 | uint8_t* reply, |
| 232 | unsigned max_reply_len, |
| 233 | int recvmsg_flags, |
| 234 | int* result_fd, |
| 235 | const Pickle& request) { |
[email protected] | 43235a0 | 2009-06-18 00:44:42 | [diff] [blame] | 236 | // This socketpair is only used for the IPC and is cleaned up before |
| 237 | // returning. |
brettw | a027ae3 | 2015-06-02 19:48:29 | [diff] [blame] | 238 | ScopedFD recv_sock, send_sock; |
Peter Kasting | 134ef9af | 2024-12-28 02:30:09 | [diff] [blame] | 239 | if (!CreateSocketPair(&recv_sock, &send_sock)) { |
[email protected] | 6729422d | 2012-10-12 05:51:18 | [diff] [blame] | 240 | return -1; |
Peter Kasting | 134ef9af | 2024-12-28 02:30:09 | [diff] [blame] | 241 | } |
[email protected] | 43235a0 | 2009-06-18 00:44:42 | [diff] [blame] | 242 | |
[email protected] | 8feaa67 | 2014-04-30 21:57:10 | [diff] [blame] | 243 | { |
| 244 | std::vector<int> send_fds; |
| 245 | send_fds.push_back(send_sock.get()); |
Peter Kasting | 134ef9af | 2024-12-28 02:30:09 | [diff] [blame] | 246 | if (!SendMsg(fd, request.data(), request.size(), send_fds)) { |
[email protected] | 8feaa67 | 2014-04-30 21:57:10 | [diff] [blame] | 247 | return -1; |
Peter Kasting | 134ef9af | 2024-12-28 02:30:09 | [diff] [blame] | 248 | } |
[email protected] | 43235a0 | 2009-06-18 00:44:42 | [diff] [blame] | 249 | } |
[email protected] | 43235a0 | 2009-06-18 00:44:42 | [diff] [blame] | 250 | |
[email protected] | 8feaa67 | 2014-04-30 21:57:10 | [diff] [blame] | 251 | // Close the sending end of the socket right away so that if our peer closes |
| 252 | // it before sending a response (e.g., from exiting), RecvMsgWithFlags() will |
| 253 | // return EOF instead of hanging. |
| 254 | send_sock.reset(); |
| 255 | |
mdempsky | f12295a | 2015-12-09 22:54:46 | [diff] [blame] | 256 | std::vector<ScopedFD> recv_fds; |
[email protected] | 1dc3796b | 2014-04-24 23:42:42 | [diff] [blame] | 257 | const ssize_t reply_len = RecvMsgWithFlags( |
Ivan Kotenkov | a16212a5 | 2017-11-08 12:37:33 | [diff] [blame] | 258 | recv_sock.get(), reply, max_reply_len, recvmsg_flags, &recv_fds, nullptr); |
[email protected] | 8feaa67 | 2014-04-30 21:57:10 | [diff] [blame] | 259 | recv_sock.reset(); |
Peter Kasting | 134ef9af | 2024-12-28 02:30:09 | [diff] [blame] | 260 | if (reply_len == -1) { |
[email protected] | 43235a0 | 2009-06-18 00:44:42 | [diff] [blame] | 261 | return -1; |
Peter Kasting | 134ef9af | 2024-12-28 02:30:09 | [diff] [blame] | 262 | } |
[email protected] | 43235a0 | 2009-06-18 00:44:42 | [diff] [blame] | 263 | |
[email protected] | 8feaa67 | 2014-04-30 21:57:10 | [diff] [blame] | 264 | // If we received more file descriptors than caller expected, then we treat |
| 265 | // that as an error. |
Ivan Kotenkov | a16212a5 | 2017-11-08 12:37:33 | [diff] [blame] | 266 | if (recv_fds.size() > (result_fd != nullptr ? 1 : 0)) { |
Peter Boström | de57333 | 2024-08-26 20:42:45 | [diff] [blame] | 267 | NOTREACHED(); |
[email protected] | 43235a0 | 2009-06-18 00:44:42 | [diff] [blame] | 268 | } |
| 269 | |
Peter Kasting | 134ef9af | 2024-12-28 02:30:09 | [diff] [blame] | 270 | if (result_fd) { |
mdempsky | f12295a | 2015-12-09 22:54:46 | [diff] [blame] | 271 | *result_fd = recv_fds.empty() ? -1 : recv_fds[0].release(); |
Peter Kasting | 134ef9af | 2024-12-28 02:30:09 | [diff] [blame] | 272 | } |
[email protected] | 43235a0 | 2009-06-18 00:44:42 | [diff] [blame] | 273 | |
| 274 | return reply_len; |
| 275 | } |
brettw | a027ae3 | 2015-06-02 19:48:29 | [diff] [blame] | 276 | |
| 277 | } // namespace base |