ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/IO-FDPass/FDPass.xs
(Generate patch)

Comparing IO-FDPass/FDPass.xs (file contents):
Revision 1.5 by root, Fri Apr 5 08:20:36 2013 UTC vs.
Revision 1.9 by root, Tue Sep 6 10:49:13 2022 UTC

32 #include <sys/types.h> 32 #include <sys/types.h>
33 #include <sys/uio.h> 33 #include <sys/uio.h>
34 #include <sys/socket.h> 34 #include <sys/socket.h>
35 35
36 #ifndef CMSG_SPACE 36 #ifndef CMSG_SPACE
37 # define CMSG_SPACE(len) (sizeof (cmsghdr) + len) 37 # define CMSG_SPACE(len) (sizeof (struct cmsghdr) + len)
38 #endif 38 #endif
39 39
40 #ifndef CMSG_LEN 40 #ifndef CMSG_LEN
41 # define CMSG_LEN(len) (sizeof (cmsghdr) + len) 41 # define CMSG_LEN(len) (sizeof (struct cmsghdr) + len)
42 #endif 42 #endif
43 43
44#endif 44#endif
45 45
46#if defined(WIN32) 46#if defined(WIN32)
189 msg.msg_iovlen = 1; 189 msg.msg_iovlen = 1;
190 msg.msg_control = buf; 190 msg.msg_control = buf;
191 msg.msg_controllen = CMSG_SPACE (sizeof (int)); 191 msg.msg_controllen = CMSG_SPACE (sizeof (int));
192 192
193 if (recvmsg (socket, &msg, 0) <= 0) 193 if (recvmsg (socket, &msg, 0) <= 0)
194 {
195 free (buf);
194 return -1; 196 return -1;
197 }
195 198
196 int fd = -1; 199 int fd = -1;
197 200
201 struct cmsghdr *cmsg = CMSG_FIRSTHDR (&msg);
202
203 if (cmsg)
204 {
205 // some operating systems (i.e. osx) allow msg->cmsg_len to be larger than
206 // msg.msg_controllen, so limit the size here
207 if (cmsg->cmsg_len > CMSG_SPACE (sizeof (int)))
208 cmsg->cmsg_len = CMSG_SPACE (sizeof (int));
209
210 if ( cmsg->cmsg_level == SOL_SOCKET
211 && cmsg->cmsg_type == SCM_RIGHTS
212 && cmsg->cmsg_len >= CMSG_LEN (sizeof (int)))
213 {
214 // close any extra fd's that might have been passed.
215 // this does not work around osx/freebsad bugs where a malicious sender
216 // can send usw more fds than we can receive, leaking the extra fds,
217 // which must be fixed in the kernel, really.
218 for (fd = 1; cmsg->cmsg_len >= CMSG_LEN (sizeof (int) * (fd + 1)); ++fd)
219 close (((int *)CMSG_DATA (cmsg))[fd]);
220
221 fd = *(int *)CMSG_DATA (cmsg);
222 }
223 }
224
225 free (buf);
226
227 if (data != 0)
228 {
229 close (fd);
230 fd = -1;
231 }
232
198 errno = EDOM; 233 errno = EDOM;
199
200 if (
201 data == 0
202#if __OpenBSD__
203 && msg.msg_controllen >= CMSG_LEN (sizeof (int)) /* work around a bug in at least openbsd 4.5 and 4.8 */
204#else
205 && msg.msg_controllen >= CMSG_SPACE (sizeof (int))
206#endif
207 ) {
208 struct cmsghdr *cmsg = CMSG_FIRSTHDR (&msg);
209
210 if (cmsg->cmsg_level == SOL_SOCKET
211 && cmsg->cmsg_type == SCM_RIGHTS
212 && cmsg->cmsg_len >= CMSG_LEN (sizeof (int)))
213 fd = *(int *)CMSG_DATA (cmsg);
214 }
215
216 free (buf);
217 234
218 return fd; 235 return fd;
219#endif 236#endif
220} 237}
221 238

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines