Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(36)

Side by Side Diff: base/posix/unix_domain_socket_linux.cc

Issue 241863002: Extend UnixDomainSocket::RecvMsg to return sender's PID (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Remove sandbox unit tests for followup CL Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "base/posix/unix_domain_socket_linux.h" 5 #include "base/posix/unix_domain_socket_linux.h"
6 6
7 #include <errno.h> 7 #include <errno.h>
8 #include <sys/socket.h> 8 #include <sys/socket.h>
9 #include <sys/uio.h> 9 #include <sys/uio.h>
10 #include <unistd.h> 10 #include <unistd.h>
11 11
12 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "base/pickle.h" 13 #include "base/pickle.h"
14 #include "base/posix/eintr_wrapper.h" 14 #include "base/posix/eintr_wrapper.h"
15 #include "base/stl_util.h" 15 #include "base/stl_util.h"
16 16
17 const size_t UnixDomainSocket::kMaxFileDescriptors = 16; 17 const size_t UnixDomainSocket::kMaxFileDescriptors = 16;
18 18
19 // static 19 // static
20 bool UnixDomainSocket::EnableReceiveProcessId(int fd) {
21 const int enable = 1;
22 return setsockopt(fd, SOL_SOCKET, SO_PASSCRED, &enable, sizeof(enable)) == 0;
23 }
24
25 // static
20 bool UnixDomainSocket::SendMsg(int fd, 26 bool UnixDomainSocket::SendMsg(int fd,
21 const void* buf, 27 const void* buf,
22 size_t length, 28 size_t length,
23 const std::vector<int>& fds) { 29 const std::vector<int>& fds) {
24 struct msghdr msg = {}; 30 struct msghdr msg = {};
25 struct iovec iov = { const_cast<void*>(buf), length }; 31 struct iovec iov = { const_cast<void*>(buf), length };
26 msg.msg_iov = &iov; 32 msg.msg_iov = &iov;
27 msg.msg_iovlen = 1; 33 msg.msg_iovlen = 1;
28 34
29 char* control_buffer = NULL; 35 char* control_buffer = NULL;
(...skipping 21 matching lines...) Expand all
51 const bool ret = static_cast<ssize_t>(length) == r; 57 const bool ret = static_cast<ssize_t>(length) == r;
52 delete[] control_buffer; 58 delete[] control_buffer;
53 return ret; 59 return ret;
54 } 60 }
55 61
56 // static 62 // static
57 ssize_t UnixDomainSocket::RecvMsg(int fd, 63 ssize_t UnixDomainSocket::RecvMsg(int fd,
58 void* buf, 64 void* buf,
59 size_t length, 65 size_t length,
60 std::vector<int>* fds) { 66 std::vector<int>* fds) {
61 return UnixDomainSocket::RecvMsgWithFlags(fd, buf, length, 0, fds); 67 return UnixDomainSocket::RecvMsgWithPid(fd, buf, length, fds, NULL);
62 } 68 }
63 69
64 // static 70 // static
71 ssize_t UnixDomainSocket::RecvMsgWithPid(int fd,
72 void* buf,
73 size_t length,
74 std::vector<int>* fds,
75 base::ProcessId* pid) {
76 return UnixDomainSocket::RecvMsgWithFlags(fd, buf, length, 0, fds, pid);
77 }
78
79 // static
65 ssize_t UnixDomainSocket::RecvMsgWithFlags(int fd, 80 ssize_t UnixDomainSocket::RecvMsgWithFlags(int fd,
66 void* buf, 81 void* buf,
67 size_t length, 82 size_t length,
68 int flags, 83 int flags,
69 std::vector<int>* fds) { 84 std::vector<int>* fds,
85 base::ProcessId* out_pid) {
70 fds->clear(); 86 fds->clear();
71 87
72 struct msghdr msg = {}; 88 struct msghdr msg = {};
73 struct iovec iov = { buf, length }; 89 struct iovec iov = { buf, length };
74 msg.msg_iov = &iov; 90 msg.msg_iov = &iov;
75 msg.msg_iovlen = 1; 91 msg.msg_iovlen = 1;
76 92
77 char control_buffer[CMSG_SPACE(sizeof(int) * kMaxFileDescriptors)]; 93 char control_buffer[CMSG_SPACE(sizeof(int) * kMaxFileDescriptors) +
94 CMSG_SPACE(sizeof(struct ucred))];
78 msg.msg_control = control_buffer; 95 msg.msg_control = control_buffer;
79 msg.msg_controllen = sizeof(control_buffer); 96 msg.msg_controllen = sizeof(control_buffer);
80 97
81 const ssize_t r = HANDLE_EINTR(recvmsg(fd, &msg, flags)); 98 const ssize_t r = HANDLE_EINTR(recvmsg(fd, &msg, flags));
82 if (r == -1) 99 if (r == -1)
83 return -1; 100 return -1;
84 101
85 int* wire_fds = NULL; 102 int* wire_fds = NULL;
86 unsigned wire_fds_len = 0; 103 unsigned wire_fds_len = 0;
104 base::ProcessId pid = -1;
87 105
88 if (msg.msg_controllen > 0) { 106 if (msg.msg_controllen > 0) {
89 struct cmsghdr* cmsg; 107 struct cmsghdr* cmsg;
90 for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) { 108 for (cmsg = CMSG_FIRSTHDR(&msg); cmsg; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
109 const unsigned payload_len = cmsg->cmsg_len - CMSG_LEN(0);
91 if (cmsg->cmsg_level == SOL_SOCKET && 110 if (cmsg->cmsg_level == SOL_SOCKET &&
92 cmsg->cmsg_type == SCM_RIGHTS) { 111 cmsg->cmsg_type == SCM_RIGHTS) {
93 const unsigned payload_len = cmsg->cmsg_len - CMSG_LEN(0);
94 DCHECK(payload_len % sizeof(int) == 0); 112 DCHECK(payload_len % sizeof(int) == 0);
113 DCHECK(wire_fds == NULL);
95 wire_fds = reinterpret_cast<int*>(CMSG_DATA(cmsg)); 114 wire_fds = reinterpret_cast<int*>(CMSG_DATA(cmsg));
96 wire_fds_len = payload_len / sizeof(int); 115 wire_fds_len = payload_len / sizeof(int);
97 break; 116 }
117 if (cmsg->cmsg_level == SOL_SOCKET &&
118 cmsg->cmsg_type == SCM_CREDENTIALS) {
119 DCHECK(payload_len == sizeof(struct ucred));
120 DCHECK(pid == -1);
121 pid = reinterpret_cast<struct ucred*>(CMSG_DATA(cmsg))->pid;
98 } 122 }
99 } 123 }
100 } 124 }
101 125
102 if (msg.msg_flags & MSG_TRUNC || msg.msg_flags & MSG_CTRUNC) { 126 if (msg.msg_flags & MSG_TRUNC || msg.msg_flags & MSG_CTRUNC) {
103 for (unsigned i = 0; i < wire_fds_len; ++i) 127 for (unsigned i = 0; i < wire_fds_len; ++i)
104 close(wire_fds[i]); 128 close(wire_fds[i]);
105 errno = EMSGSIZE; 129 errno = EMSGSIZE;
106 return -1; 130 return -1;
107 } 131 }
108 132
109 if (wire_fds) { 133 if (wire_fds) {
110 fds->resize(wire_fds_len); 134 fds->resize(wire_fds_len);
111 memcpy(vector_as_array(fds), wire_fds, sizeof(int) * wire_fds_len); 135 memcpy(vector_as_array(fds), wire_fds, sizeof(int) * wire_fds_len);
112 } 136 }
113 137
138 if (out_pid) {
139 DCHECK(pid != -1);
140 *out_pid = pid;
141 }
142
114 return r; 143 return r;
115 } 144 }
116 145
117 // static 146 // static
118 ssize_t UnixDomainSocket::SendRecvMsg(int fd, 147 ssize_t UnixDomainSocket::SendRecvMsg(int fd,
119 uint8_t* reply, 148 uint8_t* reply,
120 unsigned max_reply_len, 149 unsigned max_reply_len,
121 int* result_fd, 150 int* result_fd,
122 const Pickle& request) { 151 const Pickle& request) {
123 return UnixDomainSocket::SendRecvMsgWithFlags(fd, reply, max_reply_len, 152 return UnixDomainSocket::SendRecvMsgWithFlags(fd, reply, max_reply_len,
(...skipping 20 matching lines...) Expand all
144 if (!SendMsg(fd, request.data(), request.size(), fd_vector)) { 173 if (!SendMsg(fd, request.data(), request.size(), fd_vector)) {
145 close(fds[0]); 174 close(fds[0]);
146 close(fds[1]); 175 close(fds[1]);
147 return -1; 176 return -1;
148 } 177 }
149 close(fds[1]); 178 close(fds[1]);
150 179
151 fd_vector.clear(); 180 fd_vector.clear();
152 // When porting to OSX keep in mind it doesn't support MSG_NOSIGNAL, so the 181 // When porting to OSX keep in mind it doesn't support MSG_NOSIGNAL, so the
153 // sender might get a SIGPIPE. 182 // sender might get a SIGPIPE.
154 const ssize_t reply_len = RecvMsgWithFlags(fds[0], reply, max_reply_len, 183 const ssize_t reply_len = RecvMsgWithFlags(
155 recvmsg_flags, &fd_vector); 184 fds[0], reply, max_reply_len, recvmsg_flags, &fd_vector, NULL);
156 close(fds[0]); 185 close(fds[0]);
157 if (reply_len == -1) 186 if (reply_len == -1)
158 return -1; 187 return -1;
159 188
160 if ((!fd_vector.empty() && result_fd == NULL) || fd_vector.size() > 1) { 189 if ((!fd_vector.empty() && result_fd == NULL) || fd_vector.size() > 1) {
161 for (std::vector<int>::const_iterator 190 for (std::vector<int>::const_iterator
162 i = fd_vector.begin(); i != fd_vector.end(); ++i) { 191 i = fd_vector.begin(); i != fd_vector.end(); ++i) {
163 close(*i); 192 close(*i);
164 } 193 }
165 194
166 NOTREACHED(); 195 NOTREACHED();
167 196
168 return -1; 197 return -1;
169 } 198 }
170 199
171 if (result_fd) 200 if (result_fd)
172 *result_fd = fd_vector.empty() ? -1 : fd_vector[0]; 201 *result_fd = fd_vector.empty() ? -1 : fd_vector[0];
173 202
174 return reply_len; 203 return reply_len;
175 } 204 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698