1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
3 *
4 * Copyright (c) 1995 Søren Schmidt
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29 #include <sys/cdefs.h>
30 #include "opt_inet6.h"
31
32 #include <sys/param.h>
33 #include <sys/capsicum.h>
34 #include <sys/filedesc.h>
35 #include <sys/limits.h>
36 #include <sys/malloc.h>
37 #include <sys/mbuf.h>
38 #include <sys/proc.h>
39 #include <sys/socket.h>
40 #include <sys/socketvar.h>
41 #include <sys/syscallsubr.h>
42 #include <sys/sysproto.h>
43 #include <sys/un.h>
44 #include <sys/unistd.h>
45
46 #include <security/audit/audit.h>
47
48 #include <net/if.h>
49 #include <net/vnet.h>
50 #include <netinet/in.h>
51 #include <netinet/ip.h>
52 #include <netinet/tcp.h>
53 #ifdef INET6
54 #include <netinet/ip6.h>
55 #include <netinet6/ip6_var.h>
56 #endif
57
58 #ifdef COMPAT_LINUX32
59 #include <machine/../linux32/linux.h>
60 #include <machine/../linux32/linux32_proto.h>
61 #else
62 #include <machine/../linux/linux.h>
63 #include <machine/../linux/linux_proto.h>
64 #endif
65 #include <compat/linux/linux_common.h>
66 #include <compat/linux/linux_emul.h>
67 #include <compat/linux/linux_file.h>
68 #include <compat/linux/linux_mib.h>
69 #include <compat/linux/linux_socket.h>
70 #include <compat/linux/linux_time.h>
71 #include <compat/linux/linux_util.h>
72
73 #define SECURITY_CONTEXT_STRING "unconfined"
74
75 static int linux_sendmsg_common(struct thread *, l_int, struct l_msghdr *,
76 l_uint);
77 static int linux_recvmsg_common(struct thread *, l_int, struct l_msghdr *,
78 l_uint, struct msghdr *);
79 static int linux_set_socket_flags(int, int *);
80
81 #define SOL_NETLINK 270
82
83 static int
linux_to_bsd_sockopt_level(int level)84 linux_to_bsd_sockopt_level(int level)
85 {
86
87 if (level == LINUX_SOL_SOCKET)
88 return (SOL_SOCKET);
89 /* Remaining values are RFC-defined protocol numbers. */
90 return (level);
91 }
92
93 static int
bsd_to_linux_sockopt_level(int level)94 bsd_to_linux_sockopt_level(int level)
95 {
96
97 if (level == SOL_SOCKET)
98 return (LINUX_SOL_SOCKET);
99 return (level);
100 }
101
102 static int
linux_to_bsd_ip_sockopt(int opt)103 linux_to_bsd_ip_sockopt(int opt)
104 {
105
106 switch (opt) {
107 /* known and translated sockopts */
108 case LINUX_IP_TOS:
109 return (IP_TOS);
110 case LINUX_IP_TTL:
111 return (IP_TTL);
112 case LINUX_IP_HDRINCL:
113 return (IP_HDRINCL);
114 case LINUX_IP_OPTIONS:
115 return (IP_OPTIONS);
116 case LINUX_IP_RECVOPTS:
117 LINUX_RATELIMIT_MSG_NOTTESTED("IPv4 socket option IP_RECVOPTS");
118 return (IP_RECVOPTS);
119 case LINUX_IP_RETOPTS:
120 LINUX_RATELIMIT_MSG_NOTTESTED("IPv4 socket option IP_REETOPTS");
121 return (IP_RETOPTS);
122 case LINUX_IP_RECVTTL:
123 LINUX_RATELIMIT_MSG_NOTTESTED("IPv4 socket option IP_RECVTTL");
124 return (IP_RECVTTL);
125 case LINUX_IP_RECVTOS:
126 LINUX_RATELIMIT_MSG_NOTTESTED("IPv4 socket option IP_RECVTOS");
127 return (IP_RECVTOS);
128 case LINUX_IP_FREEBIND:
129 LINUX_RATELIMIT_MSG_NOTTESTED("IPv4 socket option IP_FREEBIND");
130 return (IP_BINDANY);
131 case LINUX_IP_IPSEC_POLICY:
132 /* we have this option, but not documented in ip(4) manpage */
133 LINUX_RATELIMIT_MSG_NOTTESTED("IPv4 socket option IP_IPSEC_POLICY");
134 return (IP_IPSEC_POLICY);
135 case LINUX_IP_MINTTL:
136 LINUX_RATELIMIT_MSG_NOTTESTED("IPv4 socket option IP_MINTTL");
137 return (IP_MINTTL);
138 case LINUX_IP_MULTICAST_IF:
139 return (IP_MULTICAST_IF);
140 case LINUX_IP_MULTICAST_TTL:
141 return (IP_MULTICAST_TTL);
142 case LINUX_IP_MULTICAST_LOOP:
143 return (IP_MULTICAST_LOOP);
144 case LINUX_IP_ADD_MEMBERSHIP:
145 return (IP_ADD_MEMBERSHIP);
146 case LINUX_IP_DROP_MEMBERSHIP:
147 return (IP_DROP_MEMBERSHIP);
148 case LINUX_IP_UNBLOCK_SOURCE:
149 LINUX_RATELIMIT_MSG_NOTTESTED("IPv4 socket option IP_UNBLOCK_SOURCE");
150 return (IP_UNBLOCK_SOURCE);
151 case LINUX_IP_BLOCK_SOURCE:
152 LINUX_RATELIMIT_MSG_NOTTESTED("IPv4 socket option IP_BLOCK_SOURCE");
153 return (IP_BLOCK_SOURCE);
154 case LINUX_IP_ADD_SOURCE_MEMBERSHIP:
155 LINUX_RATELIMIT_MSG_NOTTESTED("IPv4 socket option IP_ADD_SOURCE_MEMBERSHIP");
156 return (IP_ADD_SOURCE_MEMBERSHIP);
157 case LINUX_IP_DROP_SOURCE_MEMBERSHIP:
158 LINUX_RATELIMIT_MSG_NOTTESTED("IPv4 socket option IP_DROP_SOURCE_MEMBERSHIP");
159 return (IP_DROP_SOURCE_MEMBERSHIP);
160 case LINUX_MCAST_JOIN_GROUP:
161 LINUX_RATELIMIT_MSG_NOTTESTED("IPv4 socket option IP_MCAST_JOIN_GROUP");
162 return (MCAST_JOIN_GROUP);
163 case LINUX_MCAST_LEAVE_GROUP:
164 LINUX_RATELIMIT_MSG_NOTTESTED("IPv4 socket option IP_MCAST_LEAVE_GROUP");
165 return (MCAST_LEAVE_GROUP);
166 case LINUX_MCAST_JOIN_SOURCE_GROUP:
167 LINUX_RATELIMIT_MSG_NOTTESTED("IPv4 socket option IP_MCAST_JOIN_SOURCE_GROUP");
168 return (MCAST_JOIN_SOURCE_GROUP);
169 case LINUX_MCAST_LEAVE_SOURCE_GROUP:
170 LINUX_RATELIMIT_MSG_NOTTESTED("IPv4 socket option IP_MCAST_LEAVE_SOURCE_GROUP");
171 return (MCAST_LEAVE_SOURCE_GROUP);
172 case LINUX_IP_RECVORIGDSTADDR:
173 return (IP_RECVORIGDSTADDR);
174
175 /* known but not implemented sockopts */
176 case LINUX_IP_ROUTER_ALERT:
177 LINUX_RATELIMIT_MSG_OPT1(
178 "unsupported IPv4 socket option IP_ROUTER_ALERT (%d), you can not do user-space routing from linux programs",
179 opt);
180 return (-2);
181 case LINUX_IP_PKTINFO:
182 LINUX_RATELIMIT_MSG_OPT1(
183 "unsupported IPv4 socket option IP_PKTINFO (%d), you can not get extended packet info for datagram sockets in linux programs",
184 opt);
185 return (-2);
186 case LINUX_IP_PKTOPTIONS:
187 LINUX_RATELIMIT_MSG_OPT1(
188 "unsupported IPv4 socket option IP_PKTOPTIONS (%d)",
189 opt);
190 return (-2);
191 case LINUX_IP_MTU_DISCOVER:
192 LINUX_RATELIMIT_MSG_OPT1(
193 "unsupported IPv4 socket option IP_MTU_DISCOVER (%d), your linux program can not control path-MTU discovery",
194 opt);
195 return (-2);
196 case LINUX_IP_RECVERR:
197 /* needed by steam */
198 LINUX_RATELIMIT_MSG_OPT1(
199 "unsupported IPv4 socket option IP_RECVERR (%d), you can not get extended reliability info in linux programs",
200 opt);
201 return (-2);
202 case LINUX_IP_MTU:
203 LINUX_RATELIMIT_MSG_OPT1(
204 "unsupported IPv4 socket option IP_MTU (%d), your linux program can not control the MTU on this socket",
205 opt);
206 return (-2);
207 case LINUX_IP_XFRM_POLICY:
208 LINUX_RATELIMIT_MSG_OPT1(
209 "unsupported IPv4 socket option IP_XFRM_POLICY (%d)",
210 opt);
211 return (-2);
212 case LINUX_IP_PASSSEC:
213 /* needed by steam */
214 LINUX_RATELIMIT_MSG_OPT1(
215 "unsupported IPv4 socket option IP_PASSSEC (%d), you can not get IPSEC related credential information associated with this socket in linux programs -- if you do not use IPSEC, you can ignore this",
216 opt);
217 return (-2);
218 case LINUX_IP_TRANSPARENT:
219 /* IP_BINDANY or more? */
220 LINUX_RATELIMIT_MSG_OPT1(
221 "unsupported IPv4 socket option IP_TRANSPARENT (%d), you can not enable transparent proxying in linux programs -- note, IP_FREEBIND is supported, no idea if the FreeBSD IP_BINDANY is equivalent to the Linux IP_TRANSPARENT or not, any info is welcome",
222 opt);
223 return (-2);
224 case LINUX_IP_NODEFRAG:
225 LINUX_RATELIMIT_MSG_OPT1(
226 "unsupported IPv4 socket option IP_NODEFRAG (%d)",
227 opt);
228 return (-2);
229 case LINUX_IP_CHECKSUM:
230 LINUX_RATELIMIT_MSG_OPT1(
231 "unsupported IPv4 socket option IP_CHECKSUM (%d)",
232 opt);
233 return (-2);
234 case LINUX_IP_BIND_ADDRESS_NO_PORT:
235 LINUX_RATELIMIT_MSG_OPT1(
236 "unsupported IPv4 socket option IP_BIND_ADDRESS_NO_PORT (%d)",
237 opt);
238 return (-2);
239 case LINUX_IP_RECVFRAGSIZE:
240 LINUX_RATELIMIT_MSG_OPT1(
241 "unsupported IPv4 socket option IP_RECVFRAGSIZE (%d)",
242 opt);
243 return (-2);
244 case LINUX_MCAST_MSFILTER:
245 LINUX_RATELIMIT_MSG_OPT1(
246 "unsupported IPv4 socket option IP_MCAST_MSFILTER (%d)",
247 opt);
248 return (-2);
249 case LINUX_IP_MULTICAST_ALL:
250 LINUX_RATELIMIT_MSG_OPT1(
251 "unsupported IPv4 socket option IP_MULTICAST_ALL (%d), your linux program will not see all multicast groups joined by the entire system, only those the program joined itself on this socket",
252 opt);
253 return (-2);
254 case LINUX_IP_UNICAST_IF:
255 LINUX_RATELIMIT_MSG_OPT1(
256 "unsupported IPv4 socket option IP_UNICAST_IF (%d)",
257 opt);
258 return (-2);
259
260 /* unknown sockopts */
261 default:
262 return (-1);
263 }
264 }
265
266 static int
linux_to_bsd_ip6_sockopt(int opt)267 linux_to_bsd_ip6_sockopt(int opt)
268 {
269
270 switch (opt) {
271 /* known and translated sockopts */
272 case LINUX_IPV6_2292PKTINFO:
273 LINUX_RATELIMIT_MSG_NOTTESTED("IPv6 socket option IPV6_2292PKTINFO");
274 return (IPV6_2292PKTINFO);
275 case LINUX_IPV6_2292HOPOPTS:
276 LINUX_RATELIMIT_MSG_NOTTESTED("IPv6 socket option IPV6_2292HOPOPTS");
277 return (IPV6_2292HOPOPTS);
278 case LINUX_IPV6_2292DSTOPTS:
279 LINUX_RATELIMIT_MSG_NOTTESTED("IPv6 socket option IPV6_2292DSTOPTS");
280 return (IPV6_2292DSTOPTS);
281 case LINUX_IPV6_2292RTHDR:
282 LINUX_RATELIMIT_MSG_NOTTESTED("IPv6 socket option IPV6_2292RTHDR");
283 return (IPV6_2292RTHDR);
284 case LINUX_IPV6_2292PKTOPTIONS:
285 LINUX_RATELIMIT_MSG_NOTTESTED("IPv6 socket option IPV6_2292PKTOPTIONS");
286 return (IPV6_2292PKTOPTIONS);
287 case LINUX_IPV6_CHECKSUM:
288 LINUX_RATELIMIT_MSG_NOTTESTED("IPv6 socket option IPV6_CHECKSUM");
289 return (IPV6_CHECKSUM);
290 case LINUX_IPV6_2292HOPLIMIT:
291 LINUX_RATELIMIT_MSG_NOTTESTED("IPv6 socket option IPV6_2292HOPLIMIT");
292 return (IPV6_2292HOPLIMIT);
293 case LINUX_IPV6_NEXTHOP:
294 return (IPV6_NEXTHOP);
295 case LINUX_IPV6_UNICAST_HOPS:
296 return (IPV6_UNICAST_HOPS);
297 case LINUX_IPV6_MULTICAST_IF:
298 return (IPV6_MULTICAST_IF);
299 case LINUX_IPV6_MULTICAST_HOPS:
300 return (IPV6_MULTICAST_HOPS);
301 case LINUX_IPV6_MULTICAST_LOOP:
302 return (IPV6_MULTICAST_LOOP);
303 case LINUX_IPV6_ADD_MEMBERSHIP:
304 return (IPV6_JOIN_GROUP);
305 case LINUX_IPV6_DROP_MEMBERSHIP:
306 return (IPV6_LEAVE_GROUP);
307 case LINUX_IPV6_V6ONLY:
308 return (IPV6_V6ONLY);
309 case LINUX_IPV6_IPSEC_POLICY:
310 /* we have this option, but not documented in ip6(4) manpage */
311 LINUX_RATELIMIT_MSG_NOTTESTED("IPv6 socket option IPV6_IPSEC_POLICY");
312 return (IPV6_IPSEC_POLICY);
313 case LINUX_MCAST_JOIN_GROUP:
314 LINUX_RATELIMIT_MSG_NOTTESTED("IPv6 socket option IPV6_JOIN_GROUP");
315 return (IPV6_JOIN_GROUP);
316 case LINUX_MCAST_LEAVE_GROUP:
317 LINUX_RATELIMIT_MSG_NOTTESTED("IPv6 socket option IPV6_LEAVE_GROUP");
318 return (IPV6_LEAVE_GROUP);
319 case LINUX_IPV6_RECVPKTINFO:
320 LINUX_RATELIMIT_MSG_NOTTESTED("IPv6 socket option IPV6_RECVPKTINFO");
321 return (IPV6_RECVPKTINFO);
322 case LINUX_IPV6_PKTINFO:
323 LINUX_RATELIMIT_MSG_NOTTESTED("IPv6 socket option IPV6_PKTINFO");
324 return (IPV6_PKTINFO);
325 case LINUX_IPV6_RECVHOPLIMIT:
326 LINUX_RATELIMIT_MSG_NOTTESTED("IPv6 socket option IPV6_RECVHOPLIMIT");
327 return (IPV6_RECVHOPLIMIT);
328 case LINUX_IPV6_HOPLIMIT:
329 LINUX_RATELIMIT_MSG_NOTTESTED("IPv6 socket option IPV6_HOPLIMIT");
330 return (IPV6_HOPLIMIT);
331 case LINUX_IPV6_RECVHOPOPTS:
332 LINUX_RATELIMIT_MSG_NOTTESTED("IPv6 socket option IPV6_RECVHOPOPTS");
333 return (IPV6_RECVHOPOPTS);
334 case LINUX_IPV6_HOPOPTS:
335 LINUX_RATELIMIT_MSG_NOTTESTED("IPv6 socket option IPV6_HOPOPTS");
336 return (IPV6_HOPOPTS);
337 case LINUX_IPV6_RTHDRDSTOPTS:
338 LINUX_RATELIMIT_MSG_NOTTESTED("IPv6 socket option IPV6_RTHDRDSTOPTS");
339 return (IPV6_RTHDRDSTOPTS);
340 case LINUX_IPV6_RECVRTHDR:
341 LINUX_RATELIMIT_MSG_NOTTESTED("IPv6 socket option IPV6_RECVRTHDR");
342 return (IPV6_RECVRTHDR);
343 case LINUX_IPV6_RTHDR:
344 LINUX_RATELIMIT_MSG_NOTTESTED("IPv6 socket option IPV6_RTHDR");
345 return (IPV6_RTHDR);
346 case LINUX_IPV6_RECVDSTOPTS:
347 LINUX_RATELIMIT_MSG_NOTTESTED("IPv6 socket option IPV6_RECVDSTOPTS");
348 return (IPV6_RECVDSTOPTS);
349 case LINUX_IPV6_DSTOPTS:
350 LINUX_RATELIMIT_MSG_NOTTESTED("IPv6 socket option IPV6_DSTOPTS");
351 return (IPV6_DSTOPTS);
352 case LINUX_IPV6_RECVPATHMTU:
353 LINUX_RATELIMIT_MSG_NOTTESTED("IPv6 socket option IPV6_RECVPATHMTU");
354 return (IPV6_RECVPATHMTU);
355 case LINUX_IPV6_PATHMTU:
356 LINUX_RATELIMIT_MSG_NOTTESTED("IPv6 socket option IPV6_PATHMTU");
357 return (IPV6_PATHMTU);
358 case LINUX_IPV6_DONTFRAG:
359 return (IPV6_DONTFRAG);
360 case LINUX_IPV6_AUTOFLOWLABEL:
361 LINUX_RATELIMIT_MSG_NOTTESTED("IPv6 socket option IPV6_AUTOFLOWLABEL");
362 return (IPV6_AUTOFLOWLABEL);
363 case LINUX_IPV6_ORIGDSTADDR:
364 LINUX_RATELIMIT_MSG_NOTTESTED("IPv6 socket option IPV6_ORIGDSTADDR");
365 return (IPV6_ORIGDSTADDR);
366 case LINUX_IPV6_FREEBIND:
367 LINUX_RATELIMIT_MSG_NOTTESTED("IPv6 socket option IPV6_FREEBIND");
368 return (IPV6_BINDANY);
369
370 /* known but not implemented sockopts */
371 case LINUX_IPV6_ADDRFORM:
372 LINUX_RATELIMIT_MSG_OPT1(
373 "unsupported IPv6 socket option IPV6_ADDRFORM (%d), you linux program can not convert the socket to IPv4",
374 opt);
375 return (-2);
376 case LINUX_IPV6_AUTHHDR:
377 LINUX_RATELIMIT_MSG_OPT1(
378 "unsupported IPv6 socket option IPV6_AUTHHDR (%d), your linux program can not get the authentication header info of IPv6 packets",
379 opt);
380 return (-2);
381 case LINUX_IPV6_FLOWINFO:
382 LINUX_RATELIMIT_MSG_OPT1(
383 "unsupported IPv6 socket option IPV6_FLOWINFO (%d), your linux program can not get the flowid of IPv6 packets",
384 opt);
385 return (-2);
386 case LINUX_IPV6_ROUTER_ALERT:
387 LINUX_RATELIMIT_MSG_OPT1(
388 "unsupported IPv6 socket option IPV6_ROUTER_ALERT (%d), you can not do user-space routing from linux programs",
389 opt);
390 return (-2);
391 case LINUX_IPV6_MTU_DISCOVER:
392 LINUX_RATELIMIT_MSG_OPT1(
393 "unsupported IPv6 socket option IPV6_MTU_DISCOVER (%d), your linux program can not control path-MTU discovery",
394 opt);
395 return (-2);
396 case LINUX_IPV6_MTU:
397 LINUX_RATELIMIT_MSG_OPT1(
398 "unsupported IPv6 socket option IPV6_MTU (%d), your linux program can not control the MTU on this socket",
399 opt);
400 return (-2);
401 case LINUX_IPV6_JOIN_ANYCAST:
402 LINUX_RATELIMIT_MSG_OPT1(
403 "unsupported IPv6 socket option IPV6_JOIN_ANYCAST (%d)",
404 opt);
405 return (-2);
406 case LINUX_IPV6_LEAVE_ANYCAST:
407 LINUX_RATELIMIT_MSG_OPT1(
408 "unsupported IPv6 socket option IPV6_LEAVE_ANYCAST (%d)",
409 opt);
410 return (-2);
411 case LINUX_IPV6_MULTICAST_ALL:
412 LINUX_RATELIMIT_MSG_OPT1(
413 "unsupported IPv6 socket option IPV6_MULTICAST_ALL (%d)",
414 opt);
415 return (-2);
416 case LINUX_IPV6_ROUTER_ALERT_ISOLATE:
417 LINUX_RATELIMIT_MSG_OPT1(
418 "unsupported IPv6 socket option IPV6_ROUTER_ALERT_ISOLATE (%d)",
419 opt);
420 return (-2);
421 case LINUX_IPV6_FLOWLABEL_MGR:
422 LINUX_RATELIMIT_MSG_OPT1(
423 "unsupported IPv6 socket option IPV6_FLOWLABEL_MGR (%d)",
424 opt);
425 return (-2);
426 case LINUX_IPV6_FLOWINFO_SEND:
427 LINUX_RATELIMIT_MSG_OPT1(
428 "unsupported IPv6 socket option IPV6_FLOWINFO_SEND (%d)",
429 opt);
430 return (-2);
431 case LINUX_IPV6_XFRM_POLICY:
432 LINUX_RATELIMIT_MSG_OPT1(
433 "unsupported IPv6 socket option IPV6_XFRM_POLICY (%d)",
434 opt);
435 return (-2);
436 case LINUX_IPV6_HDRINCL:
437 LINUX_RATELIMIT_MSG_OPT1(
438 "unsupported IPv6 socket option IPV6_HDRINCL (%d)",
439 opt);
440 return (-2);
441 case LINUX_MCAST_BLOCK_SOURCE:
442 LINUX_RATELIMIT_MSG_OPT1(
443 "unsupported IPv6 socket option MCAST_BLOCK_SOURCE (%d), your linux program may see more multicast stuff than it wants",
444 opt);
445 return (-2);
446 case LINUX_MCAST_UNBLOCK_SOURCE:
447 LINUX_RATELIMIT_MSG_OPT1(
448 "unsupported IPv6 socket option MCAST_UNBLOCK_SOURCE (%d), your linux program may not see all the multicast stuff it wants",
449 opt);
450 return (-2);
451 case LINUX_MCAST_JOIN_SOURCE_GROUP:
452 LINUX_RATELIMIT_MSG_OPT1(
453 "unsupported IPv6 socket option MCAST_JOIN_SOURCE_GROUP (%d), your linux program is not able to join a multicast source group",
454 opt);
455 return (-2);
456 case LINUX_MCAST_LEAVE_SOURCE_GROUP:
457 LINUX_RATELIMIT_MSG_OPT1(
458 "unsupported IPv6 socket option MCAST_LEAVE_SOURCE_GROUP (%d), your linux program is not able to leave a multicast source group -- but it was also not able to join one, so no issue",
459 opt);
460 return (-2);
461 case LINUX_MCAST_MSFILTER:
462 LINUX_RATELIMIT_MSG_OPT1(
463 "unsupported IPv6 socket option MCAST_MSFILTER (%d), your linux program can not manipulate the multicast filter, it may see more multicast data than it wants to see",
464 opt);
465 return (-2);
466 case LINUX_IPV6_ADDR_PREFERENCES:
467 LINUX_RATELIMIT_MSG_OPT1(
468 "unsupported IPv6 socket option IPV6_ADDR_PREFERENCES (%d)",
469 opt);
470 return (-2);
471 case LINUX_IPV6_MINHOPCOUNT:
472 LINUX_RATELIMIT_MSG_OPT1(
473 "unsupported IPv6 socket option IPV6_MINHOPCOUNT (%d)",
474 opt);
475 return (-2);
476 case LINUX_IPV6_TRANSPARENT:
477 /* IP_BINDANY or more? */
478 LINUX_RATELIMIT_MSG_OPT1(
479 "unsupported IPv6 socket option IPV6_TRANSPARENT (%d), you can not enable transparent proxying in linux programs -- note, IP_FREEBIND is supported, no idea if the FreeBSD IP_BINDANY is equivalent to the Linux IP_TRANSPARENT or not, any info is welcome",
480 opt);
481 return (-2);
482 case LINUX_IPV6_UNICAST_IF:
483 LINUX_RATELIMIT_MSG_OPT1(
484 "unsupported IPv6 socket option IPV6_UNICAST_IF (%d)",
485 opt);
486 return (-2);
487 case LINUX_IPV6_RECVFRAGSIZE:
488 LINUX_RATELIMIT_MSG_OPT1(
489 "unsupported IPv6 socket option IPV6_RECVFRAGSIZE (%d)",
490 opt);
491 return (-2);
492
493 /* unknown sockopts */
494 default:
495 return (-1);
496 }
497 }
498
499 static int
linux_to_bsd_so_sockopt(int opt)500 linux_to_bsd_so_sockopt(int opt)
501 {
502
503 switch (opt) {
504 case LINUX_SO_DEBUG:
505 return (SO_DEBUG);
506 case LINUX_SO_REUSEADDR:
507 return (SO_REUSEADDR);
508 case LINUX_SO_TYPE:
509 return (SO_TYPE);
510 case LINUX_SO_ERROR:
511 return (SO_ERROR);
512 case LINUX_SO_DONTROUTE:
513 return (SO_DONTROUTE);
514 case LINUX_SO_BROADCAST:
515 return (SO_BROADCAST);
516 case LINUX_SO_SNDBUF:
517 case LINUX_SO_SNDBUFFORCE:
518 return (SO_SNDBUF);
519 case LINUX_SO_RCVBUF:
520 case LINUX_SO_RCVBUFFORCE:
521 return (SO_RCVBUF);
522 case LINUX_SO_KEEPALIVE:
523 return (SO_KEEPALIVE);
524 case LINUX_SO_OOBINLINE:
525 return (SO_OOBINLINE);
526 case LINUX_SO_LINGER:
527 return (SO_LINGER);
528 case LINUX_SO_REUSEPORT:
529 return (SO_REUSEPORT_LB);
530 case LINUX_SO_PASSCRED:
531 return (LOCAL_CREDS_PERSISTENT);
532 case LINUX_SO_PEERCRED:
533 return (LOCAL_PEERCRED);
534 case LINUX_SO_RCVLOWAT:
535 return (SO_RCVLOWAT);
536 case LINUX_SO_SNDLOWAT:
537 return (SO_SNDLOWAT);
538 case LINUX_SO_RCVTIMEO:
539 return (SO_RCVTIMEO);
540 case LINUX_SO_SNDTIMEO:
541 return (SO_SNDTIMEO);
542 case LINUX_SO_TIMESTAMPO:
543 case LINUX_SO_TIMESTAMPN:
544 return (SO_TIMESTAMP);
545 case LINUX_SO_TIMESTAMPNSO:
546 case LINUX_SO_TIMESTAMPNSN:
547 return (SO_BINTIME);
548 case LINUX_SO_ACCEPTCONN:
549 return (SO_ACCEPTCONN);
550 case LINUX_SO_PROTOCOL:
551 return (SO_PROTOCOL);
552 case LINUX_SO_DOMAIN:
553 return (SO_DOMAIN);
554 }
555 return (-1);
556 }
557
558 static int
linux_to_bsd_tcp_sockopt(int opt)559 linux_to_bsd_tcp_sockopt(int opt)
560 {
561
562 switch (opt) {
563 case LINUX_TCP_NODELAY:
564 return (TCP_NODELAY);
565 case LINUX_TCP_MAXSEG:
566 return (TCP_MAXSEG);
567 case LINUX_TCP_CORK:
568 return (TCP_NOPUSH);
569 case LINUX_TCP_KEEPIDLE:
570 return (TCP_KEEPIDLE);
571 case LINUX_TCP_KEEPINTVL:
572 return (TCP_KEEPINTVL);
573 case LINUX_TCP_KEEPCNT:
574 return (TCP_KEEPCNT);
575 case LINUX_TCP_INFO:
576 LINUX_RATELIMIT_MSG_OPT1(
577 "unsupported TCP socket option TCP_INFO (%d)", opt);
578 return (-2);
579 case LINUX_TCP_MD5SIG:
580 return (TCP_MD5SIG);
581 }
582 return (-1);
583 }
584
585 static int
linux_to_bsd_msg_flags(int flags)586 linux_to_bsd_msg_flags(int flags)
587 {
588 int ret_flags = 0;
589
590 if (flags & LINUX_MSG_OOB)
591 ret_flags |= MSG_OOB;
592 if (flags & LINUX_MSG_PEEK)
593 ret_flags |= MSG_PEEK;
594 if (flags & LINUX_MSG_DONTROUTE)
595 ret_flags |= MSG_DONTROUTE;
596 if (flags & LINUX_MSG_CTRUNC)
597 ret_flags |= MSG_CTRUNC;
598 if (flags & LINUX_MSG_TRUNC)
599 ret_flags |= MSG_TRUNC;
600 if (flags & LINUX_MSG_DONTWAIT)
601 ret_flags |= MSG_DONTWAIT;
602 if (flags & LINUX_MSG_EOR)
603 ret_flags |= MSG_EOR;
604 if (flags & LINUX_MSG_WAITALL)
605 ret_flags |= MSG_WAITALL;
606 if (flags & LINUX_MSG_NOSIGNAL)
607 ret_flags |= MSG_NOSIGNAL;
608 if (flags & LINUX_MSG_PROXY)
609 LINUX_RATELIMIT_MSG_OPT1("socket message flag MSG_PROXY (%d) not handled",
610 LINUX_MSG_PROXY);
611 if (flags & LINUX_MSG_FIN)
612 LINUX_RATELIMIT_MSG_OPT1("socket message flag MSG_FIN (%d) not handled",
613 LINUX_MSG_FIN);
614 if (flags & LINUX_MSG_SYN)
615 LINUX_RATELIMIT_MSG_OPT1("socket message flag MSG_SYN (%d) not handled",
616 LINUX_MSG_SYN);
617 if (flags & LINUX_MSG_CONFIRM)
618 LINUX_RATELIMIT_MSG_OPT1("socket message flag MSG_CONFIRM (%d) not handled",
619 LINUX_MSG_CONFIRM);
620 if (flags & LINUX_MSG_RST)
621 LINUX_RATELIMIT_MSG_OPT1("socket message flag MSG_RST (%d) not handled",
622 LINUX_MSG_RST);
623 if (flags & LINUX_MSG_ERRQUEUE)
624 LINUX_RATELIMIT_MSG_OPT1("socket message flag MSG_ERRQUEUE (%d) not handled",
625 LINUX_MSG_ERRQUEUE);
626 return (ret_flags);
627 }
628
629 static int
linux_to_bsd_cmsg_type(int cmsg_type)630 linux_to_bsd_cmsg_type(int cmsg_type)
631 {
632
633 switch (cmsg_type) {
634 case LINUX_SCM_RIGHTS:
635 return (SCM_RIGHTS);
636 case LINUX_SCM_CREDENTIALS:
637 return (SCM_CREDS);
638 }
639 return (-1);
640 }
641
642 static int
bsd_to_linux_ip_cmsg_type(int cmsg_type)643 bsd_to_linux_ip_cmsg_type(int cmsg_type)
644 {
645
646 switch (cmsg_type) {
647 case IP_RECVORIGDSTADDR:
648 return (LINUX_IP_RECVORIGDSTADDR);
649 }
650 return (-1);
651 }
652
653 static int
bsd_to_linux_cmsg_type(struct proc * p,int cmsg_type,int cmsg_level)654 bsd_to_linux_cmsg_type(struct proc *p, int cmsg_type, int cmsg_level)
655 {
656 struct linux_pemuldata *pem;
657
658 if (cmsg_level == IPPROTO_IP)
659 return (bsd_to_linux_ip_cmsg_type(cmsg_type));
660 if (cmsg_level != SOL_SOCKET)
661 return (-1);
662
663 pem = pem_find(p);
664
665 switch (cmsg_type) {
666 case SCM_RIGHTS:
667 return (LINUX_SCM_RIGHTS);
668 case SCM_CREDS:
669 return (LINUX_SCM_CREDENTIALS);
670 case SCM_CREDS2:
671 return (LINUX_SCM_CREDENTIALS);
672 case SCM_TIMESTAMP:
673 return (pem->so_timestamp);
674 case SCM_BINTIME:
675 return (pem->so_timestampns);
676 }
677 return (-1);
678 }
679
680 static int
linux_to_bsd_msghdr(struct msghdr * bhdr,const struct l_msghdr * lhdr)681 linux_to_bsd_msghdr(struct msghdr *bhdr, const struct l_msghdr *lhdr)
682 {
683 if (lhdr->msg_controllen > INT_MAX)
684 return (ENOBUFS);
685
686 bhdr->msg_name = PTRIN(lhdr->msg_name);
687 bhdr->msg_namelen = lhdr->msg_namelen;
688 bhdr->msg_iov = PTRIN(lhdr->msg_iov);
689 bhdr->msg_iovlen = lhdr->msg_iovlen;
690 bhdr->msg_control = PTRIN(lhdr->msg_control);
691
692 /*
693 * msg_controllen is skipped since BSD and LINUX control messages
694 * are potentially different sizes (e.g. the cred structure used
695 * by SCM_CREDS is different between the two operating system).
696 *
697 * The caller can set it (if necessary) after converting all the
698 * control messages.
699 */
700
701 bhdr->msg_flags = linux_to_bsd_msg_flags(lhdr->msg_flags);
702 return (0);
703 }
704
705 static int
bsd_to_linux_msghdr(const struct msghdr * bhdr,struct l_msghdr * lhdr)706 bsd_to_linux_msghdr(const struct msghdr *bhdr, struct l_msghdr *lhdr)
707 {
708 lhdr->msg_name = PTROUT(bhdr->msg_name);
709 lhdr->msg_namelen = bhdr->msg_namelen;
710 lhdr->msg_iov = PTROUT(bhdr->msg_iov);
711 lhdr->msg_iovlen = bhdr->msg_iovlen;
712 lhdr->msg_control = PTROUT(bhdr->msg_control);
713
714 /*
715 * msg_controllen is skipped since BSD and LINUX control messages
716 * are potentially different sizes (e.g. the cred structure used
717 * by SCM_CREDS is different between the two operating system).
718 *
719 * The caller can set it (if necessary) after converting all the
720 * control messages.
721 */
722
723 /* msg_flags skipped */
724 return (0);
725 }
726
727 static int
linux_set_socket_flags(int lflags,int * flags)728 linux_set_socket_flags(int lflags, int *flags)
729 {
730
731 if (lflags & ~(LINUX_SOCK_CLOEXEC | LINUX_SOCK_NONBLOCK))
732 return (EINVAL);
733 if (lflags & LINUX_SOCK_NONBLOCK)
734 *flags |= SOCK_NONBLOCK;
735 if (lflags & LINUX_SOCK_CLOEXEC)
736 *flags |= SOCK_CLOEXEC;
737 return (0);
738 }
739
740 static int
linux_copyout_sockaddr(const struct sockaddr * sa,void * uaddr,size_t len)741 linux_copyout_sockaddr(const struct sockaddr *sa, void *uaddr, size_t len)
742 {
743 struct l_sockaddr *lsa;
744 int error;
745
746 error = bsd_to_linux_sockaddr(sa, &lsa, len);
747 if (error != 0)
748 return (error);
749
750 error = copyout(lsa, uaddr, len);
751 free(lsa, M_LINUX);
752
753 return (error);
754 }
755
756 static int
linux_sendit(struct thread * td,int s,struct msghdr * mp,int flags,struct mbuf * control,enum uio_seg segflg)757 linux_sendit(struct thread *td, int s, struct msghdr *mp, int flags,
758 struct mbuf *control, enum uio_seg segflg)
759 {
760 struct sockaddr *to;
761 int error, len;
762
763 if (mp->msg_name != NULL) {
764 len = mp->msg_namelen;
765 error = linux_to_bsd_sockaddr(mp->msg_name, &to, &len);
766 if (error != 0)
767 return (error);
768 mp->msg_name = to;
769 } else
770 to = NULL;
771
772 error = kern_sendit(td, s, mp, linux_to_bsd_msg_flags(flags), control,
773 segflg);
774
775 if (to)
776 free(to, M_SONAME);
777 return (error);
778 }
779
780 /* Return 0 if IP_HDRINCL is set for the given socket. */
781 static int
linux_check_hdrincl(struct thread * td,int s)782 linux_check_hdrincl(struct thread *td, int s)
783 {
784 int error, optval;
785 socklen_t size_val;
786
787 size_val = sizeof(optval);
788 error = kern_getsockopt(td, s, IPPROTO_IP, IP_HDRINCL,
789 &optval, UIO_SYSSPACE, &size_val);
790 if (error != 0)
791 return (error);
792
793 return (optval == 0);
794 }
795
796 /*
797 * Updated sendto() when IP_HDRINCL is set:
798 * tweak endian-dependent fields in the IP packet.
799 */
800 static int
linux_sendto_hdrincl(struct thread * td,struct linux_sendto_args * linux_args)801 linux_sendto_hdrincl(struct thread *td, struct linux_sendto_args *linux_args)
802 {
803 /*
804 * linux_ip_copysize defines how many bytes we should copy
805 * from the beginning of the IP packet before we customize it for BSD.
806 * It should include all the fields we modify (ip_len and ip_off).
807 */
808 #define linux_ip_copysize 8
809
810 struct ip *packet;
811 struct msghdr msg;
812 struct iovec aiov[1];
813 int error;
814
815 /* Check that the packet isn't too big or too small. */
816 if (linux_args->len < linux_ip_copysize ||
817 linux_args->len > IP_MAXPACKET)
818 return (EINVAL);
819
820 packet = (struct ip *)malloc(linux_args->len, M_LINUX, M_WAITOK);
821
822 /* Make kernel copy of the packet to be sent */
823 if ((error = copyin(PTRIN(linux_args->msg), packet,
824 linux_args->len)))
825 goto goout;
826
827 /* Convert fields from Linux to BSD raw IP socket format */
828 packet->ip_len = linux_args->len;
829 packet->ip_off = ntohs(packet->ip_off);
830
831 /* Prepare the msghdr and iovec structures describing the new packet */
832 msg.msg_name = PTRIN(linux_args->to);
833 msg.msg_namelen = linux_args->tolen;
834 msg.msg_iov = aiov;
835 msg.msg_iovlen = 1;
836 msg.msg_control = NULL;
837 msg.msg_flags = 0;
838 aiov[0].iov_base = (char *)packet;
839 aiov[0].iov_len = linux_args->len;
840 error = linux_sendit(td, linux_args->s, &msg, linux_args->flags,
841 NULL, UIO_SYSSPACE);
842 goout:
843 free(packet, M_LINUX);
844 return (error);
845 }
846
847 static const char *linux_netlink_names[] = {
848 [LINUX_NETLINK_ROUTE] = "ROUTE",
849 [LINUX_NETLINK_SOCK_DIAG] = "SOCK_DIAG",
850 [LINUX_NETLINK_NFLOG] = "NFLOG",
851 [LINUX_NETLINK_SELINUX] = "SELINUX",
852 [LINUX_NETLINK_AUDIT] = "AUDIT",
853 [LINUX_NETLINK_FIB_LOOKUP] = "FIB_LOOKUP",
854 [LINUX_NETLINK_NETFILTER] = "NETFILTER",
855 [LINUX_NETLINK_KOBJECT_UEVENT] = "KOBJECT_UEVENT",
856 };
857
858 int
linux_socket(struct thread * td,struct linux_socket_args * args)859 linux_socket(struct thread *td, struct linux_socket_args *args)
860 {
861 int domain, retval_socket, type;
862
863 type = args->type & LINUX_SOCK_TYPE_MASK;
864 if (type < 0 || type > LINUX_SOCK_MAX)
865 return (EINVAL);
866 retval_socket = linux_set_socket_flags(args->type & ~LINUX_SOCK_TYPE_MASK,
867 &type);
868 if (retval_socket != 0)
869 return (retval_socket);
870 domain = linux_to_bsd_domain(args->domain);
871 if (domain == -1) {
872 /* Mask off SOCK_NONBLOCK / CLOEXEC for error messages. */
873 type = args->type & LINUX_SOCK_TYPE_MASK;
874 if (args->domain == LINUX_AF_NETLINK &&
875 args->protocol == LINUX_NETLINK_AUDIT) {
876 ; /* Do nothing, quietly. */
877 } else if (args->domain == LINUX_AF_NETLINK) {
878 const char *nl_name;
879
880 if (args->protocol >= 0 &&
881 args->protocol < nitems(linux_netlink_names))
882 nl_name = linux_netlink_names[args->protocol];
883 else
884 nl_name = NULL;
885 if (nl_name != NULL)
886 linux_msg(curthread,
887 "unsupported socket(AF_NETLINK, %d, "
888 "NETLINK_%s)", type, nl_name);
889 else
890 linux_msg(curthread,
891 "unsupported socket(AF_NETLINK, %d, %d)",
892 type, args->protocol);
893 } else {
894 linux_msg(curthread, "unsupported socket domain %d, "
895 "type %d, protocol %d", args->domain, type,
896 args->protocol);
897 }
898 return (EAFNOSUPPORT);
899 }
900
901 retval_socket = kern_socket(td, domain, type, args->protocol);
902 if (retval_socket)
903 return (retval_socket);
904
905 if (type == SOCK_RAW
906 && (args->protocol == IPPROTO_RAW || args->protocol == 0)
907 && domain == PF_INET) {
908 /* It's a raw IP socket: set the IP_HDRINCL option. */
909 int hdrincl;
910
911 hdrincl = 1;
912 /* We ignore any error returned by kern_setsockopt() */
913 kern_setsockopt(td, td->td_retval[0], IPPROTO_IP, IP_HDRINCL,
914 &hdrincl, UIO_SYSSPACE, sizeof(hdrincl));
915 }
916 #ifdef INET6
917 /*
918 * Linux AF_INET6 socket has IPV6_V6ONLY setsockopt set to 0 by default
919 * and some apps depend on this. So, set V6ONLY to 0 for Linux apps.
920 * For simplicity we do this unconditionally of the net.inet6.ip6.v6only
921 * sysctl value.
922 */
923 if (domain == PF_INET6) {
924 int v6only;
925
926 v6only = 0;
927 /* We ignore any error returned by setsockopt() */
928 kern_setsockopt(td, td->td_retval[0], IPPROTO_IPV6, IPV6_V6ONLY,
929 &v6only, UIO_SYSSPACE, sizeof(v6only));
930 }
931 #endif
932
933 return (retval_socket);
934 }
935
936 int
linux_bind(struct thread * td,struct linux_bind_args * args)937 linux_bind(struct thread *td, struct linux_bind_args *args)
938 {
939 struct sockaddr *sa;
940 int error;
941
942 error = linux_to_bsd_sockaddr(PTRIN(args->name), &sa,
943 &args->namelen);
944 if (error != 0)
945 return (error);
946
947 error = kern_bindat(td, AT_FDCWD, args->s, sa);
948 free(sa, M_SONAME);
949
950 /* XXX */
951 if (error == EADDRNOTAVAIL && args->namelen != sizeof(struct sockaddr_in))
952 return (EINVAL);
953 return (error);
954 }
955
956 int
linux_connect(struct thread * td,struct linux_connect_args * args)957 linux_connect(struct thread *td, struct linux_connect_args *args)
958 {
959 struct socket *so;
960 struct sockaddr *sa;
961 struct file *fp;
962 u_int fflag;
963 int error;
964
965 error = linux_to_bsd_sockaddr(PTRIN(args->name), &sa,
966 &args->namelen);
967 if (error != 0)
968 return (error);
969
970 error = kern_connectat(td, AT_FDCWD, args->s, sa);
971 free(sa, M_SONAME);
972 if (error != EISCONN)
973 return (error);
974
975 /*
976 * Linux doesn't return EISCONN the first time it occurs,
977 * when on a non-blocking socket. Instead it returns the
978 * error getsockopt(SOL_SOCKET, SO_ERROR) would return on BSD.
979 */
980 error = getsock_cap(td, args->s, &cap_connect_rights,
981 &fp, &fflag, NULL);
982 if (error != 0)
983 return (error);
984
985 error = EISCONN;
986 so = fp->f_data;
987 if (fflag & FNONBLOCK) {
988 SOCK_LOCK(so);
989 if (so->so_emuldata == 0)
990 error = so->so_error;
991 so->so_emuldata = (void *)1;
992 SOCK_UNLOCK(so);
993 }
994 fdrop(fp, td);
995
996 return (error);
997 }
998
999 int
linux_listen(struct thread * td,struct linux_listen_args * args)1000 linux_listen(struct thread *td, struct linux_listen_args *args)
1001 {
1002
1003 return (kern_listen(td, args->s, args->backlog));
1004 }
1005
1006 static int
linux_accept_common(struct thread * td,int s,l_uintptr_t addr,l_uintptr_t namelen,int flags)1007 linux_accept_common(struct thread *td, int s, l_uintptr_t addr,
1008 l_uintptr_t namelen, int flags)
1009 {
1010 struct sockaddr *sa;
1011 struct file *fp, *fp1;
1012 int bflags, len;
1013 struct socket *so;
1014 int error, error1;
1015
1016 bflags = 0;
1017 fp = NULL;
1018 sa = NULL;
1019
1020 error = linux_set_socket_flags(flags, &bflags);
1021 if (error != 0)
1022 return (error);
1023
1024 if (PTRIN(addr) == NULL) {
1025 len = 0;
1026 error = kern_accept4(td, s, NULL, NULL, bflags, NULL);
1027 } else {
1028 error = copyin(PTRIN(namelen), &len, sizeof(len));
1029 if (error != 0)
1030 return (error);
1031 if (len < 0)
1032 return (EINVAL);
1033 error = kern_accept4(td, s, &sa, &len, bflags, &fp);
1034 }
1035
1036 /*
1037 * Translate errno values into ones used by Linux.
1038 */
1039 if (error != 0) {
1040 /*
1041 * XXX. This is wrong, different sockaddr structures
1042 * have different sizes.
1043 */
1044 switch (error) {
1045 case EFAULT:
1046 if (namelen != sizeof(struct sockaddr_in))
1047 error = EINVAL;
1048 break;
1049 case EINVAL:
1050 error1 = getsock_cap(td, s, &cap_accept_rights, &fp1, NULL, NULL);
1051 if (error1 != 0) {
1052 error = error1;
1053 break;
1054 }
1055 so = fp1->f_data;
1056 if (so->so_type == SOCK_DGRAM)
1057 error = EOPNOTSUPP;
1058 fdrop(fp1, td);
1059 break;
1060 }
1061 return (error);
1062 }
1063
1064 if (len != 0) {
1065 error = linux_copyout_sockaddr(sa, PTRIN(addr), len);
1066 if (error == 0)
1067 error = copyout(&len, PTRIN(namelen),
1068 sizeof(len));
1069 if (error != 0) {
1070 fdclose(td, fp, td->td_retval[0]);
1071 td->td_retval[0] = 0;
1072 }
1073 }
1074 if (fp != NULL)
1075 fdrop(fp, td);
1076 free(sa, M_SONAME);
1077 return (error);
1078 }
1079
1080 int
linux_accept(struct thread * td,struct linux_accept_args * args)1081 linux_accept(struct thread *td, struct linux_accept_args *args)
1082 {
1083
1084 return (linux_accept_common(td, args->s, args->addr,
1085 args->namelen, 0));
1086 }
1087
1088 int
linux_accept4(struct thread * td,struct linux_accept4_args * args)1089 linux_accept4(struct thread *td, struct linux_accept4_args *args)
1090 {
1091
1092 return (linux_accept_common(td, args->s, args->addr,
1093 args->namelen, args->flags));
1094 }
1095
1096 int
linux_getsockname(struct thread * td,struct linux_getsockname_args * args)1097 linux_getsockname(struct thread *td, struct linux_getsockname_args *args)
1098 {
1099 struct sockaddr *sa;
1100 int len, error;
1101
1102 error = copyin(PTRIN(args->namelen), &len, sizeof(len));
1103 if (error != 0)
1104 return (error);
1105
1106 error = kern_getsockname(td, args->s, &sa, &len);
1107 if (error != 0)
1108 return (error);
1109
1110 if (len != 0)
1111 error = linux_copyout_sockaddr(sa, PTRIN(args->addr), len);
1112
1113 free(sa, M_SONAME);
1114 if (error == 0)
1115 error = copyout(&len, PTRIN(args->namelen), sizeof(len));
1116 return (error);
1117 }
1118
1119 int
linux_getpeername(struct thread * td,struct linux_getpeername_args * args)1120 linux_getpeername(struct thread *td, struct linux_getpeername_args *args)
1121 {
1122 struct sockaddr *sa;
1123 int len, error;
1124
1125 error = copyin(PTRIN(args->namelen), &len, sizeof(len));
1126 if (error != 0)
1127 return (error);
1128 if (len < 0)
1129 return (EINVAL);
1130
1131 error = kern_getpeername(td, args->s, &sa, &len);
1132 if (error != 0)
1133 return (error);
1134
1135 if (len != 0)
1136 error = linux_copyout_sockaddr(sa, PTRIN(args->addr), len);
1137
1138 free(sa, M_SONAME);
1139 if (error == 0)
1140 error = copyout(&len, PTRIN(args->namelen), sizeof(len));
1141 return (error);
1142 }
1143
1144 int
linux_socketpair(struct thread * td,struct linux_socketpair_args * args)1145 linux_socketpair(struct thread *td, struct linux_socketpair_args *args)
1146 {
1147 int domain, error, sv[2], type;
1148
1149 domain = linux_to_bsd_domain(args->domain);
1150 if (domain != PF_LOCAL)
1151 return (EAFNOSUPPORT);
1152 type = args->type & LINUX_SOCK_TYPE_MASK;
1153 if (type < 0 || type > LINUX_SOCK_MAX)
1154 return (EINVAL);
1155 error = linux_set_socket_flags(args->type & ~LINUX_SOCK_TYPE_MASK,
1156 &type);
1157 if (error != 0)
1158 return (error);
1159 if (args->protocol != 0 && args->protocol != PF_UNIX) {
1160 /*
1161 * Use of PF_UNIX as protocol argument is not right,
1162 * but Linux does it.
1163 * Do not map PF_UNIX as its Linux value is identical
1164 * to FreeBSD one.
1165 */
1166 return (EPROTONOSUPPORT);
1167 }
1168 error = kern_socketpair(td, domain, type, 0, sv);
1169 if (error != 0)
1170 return (error);
1171 error = copyout(sv, PTRIN(args->rsv), 2 * sizeof(int));
1172 if (error != 0) {
1173 (void)kern_close(td, sv[0]);
1174 (void)kern_close(td, sv[1]);
1175 }
1176 return (error);
1177 }
1178
1179 #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32))
1180 struct linux_send_args {
1181 register_t s;
1182 register_t msg;
1183 register_t len;
1184 register_t flags;
1185 };
1186
1187 static int
linux_send(struct thread * td,struct linux_send_args * args)1188 linux_send(struct thread *td, struct linux_send_args *args)
1189 {
1190 struct sendto_args /* {
1191 int s;
1192 caddr_t buf;
1193 int len;
1194 int flags;
1195 caddr_t to;
1196 int tolen;
1197 } */ bsd_args;
1198 struct file *fp;
1199 int error, fflag;
1200
1201 bsd_args.s = args->s;
1202 bsd_args.buf = (caddr_t)PTRIN(args->msg);
1203 bsd_args.len = args->len;
1204 bsd_args.flags = linux_to_bsd_msg_flags(args->flags);
1205 bsd_args.to = NULL;
1206 bsd_args.tolen = 0;
1207 error = sys_sendto(td, &bsd_args);
1208 if (error == ENOTCONN) {
1209 /*
1210 * Linux doesn't return ENOTCONN for non-blocking sockets.
1211 * Instead it returns the EAGAIN.
1212 */
1213 error = getsock_cap(td, args->s, &cap_send_rights, &fp,
1214 &fflag, NULL);
1215 if (error == 0) {
1216 if (fflag & FNONBLOCK)
1217 error = EAGAIN;
1218 fdrop(fp, td);
1219 }
1220 }
1221 return (error);
1222 }
1223
1224 struct linux_recv_args {
1225 register_t s;
1226 register_t msg;
1227 register_t len;
1228 register_t flags;
1229 };
1230
1231 static int
linux_recv(struct thread * td,struct linux_recv_args * args)1232 linux_recv(struct thread *td, struct linux_recv_args *args)
1233 {
1234 struct recvfrom_args /* {
1235 int s;
1236 caddr_t buf;
1237 int len;
1238 int flags;
1239 struct sockaddr *from;
1240 socklen_t fromlenaddr;
1241 } */ bsd_args;
1242
1243 bsd_args.s = args->s;
1244 bsd_args.buf = (caddr_t)PTRIN(args->msg);
1245 bsd_args.len = args->len;
1246 bsd_args.flags = linux_to_bsd_msg_flags(args->flags);
1247 bsd_args.from = NULL;
1248 bsd_args.fromlenaddr = 0;
1249 return (sys_recvfrom(td, &bsd_args));
1250 }
1251 #endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */
1252
1253 int
linux_sendto(struct thread * td,struct linux_sendto_args * args)1254 linux_sendto(struct thread *td, struct linux_sendto_args *args)
1255 {
1256 struct msghdr msg;
1257 struct iovec aiov;
1258 struct socket *so;
1259 struct file *fp;
1260 int error;
1261
1262 if (linux_check_hdrincl(td, args->s) == 0)
1263 /* IP_HDRINCL set, tweak the packet before sending */
1264 return (linux_sendto_hdrincl(td, args));
1265
1266 bzero(&msg, sizeof(msg));
1267 error = getsock_cap(td, args->s, &cap_send_connect_rights,
1268 &fp, NULL, NULL);
1269 if (error != 0)
1270 return (error);
1271 so = fp->f_data;
1272 if ((so->so_state & (SS_ISCONNECTED|SS_ISCONNECTING)) == 0) {
1273 msg.msg_name = PTRIN(args->to);
1274 msg.msg_namelen = args->tolen;
1275 }
1276 msg.msg_iov = &aiov;
1277 msg.msg_iovlen = 1;
1278 aiov.iov_base = PTRIN(args->msg);
1279 aiov.iov_len = args->len;
1280 fdrop(fp, td);
1281 return (linux_sendit(td, args->s, &msg, args->flags, NULL,
1282 UIO_USERSPACE));
1283 }
1284
1285 int
linux_recvfrom(struct thread * td,struct linux_recvfrom_args * args)1286 linux_recvfrom(struct thread *td, struct linux_recvfrom_args *args)
1287 {
1288 struct sockaddr *sa;
1289 struct msghdr msg;
1290 struct iovec aiov;
1291 int error, fromlen;
1292
1293 if (PTRIN(args->fromlen) != NULL) {
1294 error = copyin(PTRIN(args->fromlen), &fromlen,
1295 sizeof(fromlen));
1296 if (error != 0)
1297 return (error);
1298 if (fromlen < 0)
1299 return (EINVAL);
1300 fromlen = min(fromlen, SOCK_MAXADDRLEN);
1301 sa = malloc(fromlen, M_SONAME, M_WAITOK);
1302 } else {
1303 fromlen = 0;
1304 sa = NULL;
1305 }
1306
1307 msg.msg_name = sa;
1308 msg.msg_namelen = fromlen;
1309 msg.msg_iov = &aiov;
1310 msg.msg_iovlen = 1;
1311 aiov.iov_base = PTRIN(args->buf);
1312 aiov.iov_len = args->len;
1313 msg.msg_control = 0;
1314 msg.msg_flags = linux_to_bsd_msg_flags(args->flags);
1315
1316 error = kern_recvit(td, args->s, &msg, UIO_SYSSPACE, NULL);
1317 if (error != 0)
1318 goto out;
1319
1320 /*
1321 * XXX. Seems that FreeBSD is different from Linux here. Linux
1322 * fill source address if underlying protocol provides it, while
1323 * FreeBSD fill it if underlying protocol is not connection-oriented.
1324 * So, kern_recvit() set msg.msg_namelen to 0 if protocol pr_flags
1325 * does not contains PR_ADDR flag.
1326 */
1327 if (PTRIN(args->from) != NULL && msg.msg_namelen != 0)
1328 error = linux_copyout_sockaddr(sa, PTRIN(args->from),
1329 msg.msg_namelen);
1330
1331 if (error == 0 && PTRIN(args->fromlen) != NULL)
1332 error = copyout(&msg.msg_namelen, PTRIN(args->fromlen),
1333 sizeof(msg.msg_namelen));
1334 out:
1335 free(sa, M_SONAME);
1336 return (error);
1337 }
1338
1339 static int
linux_sendmsg_common(struct thread * td,l_int s,struct l_msghdr * msghdr,l_uint flags)1340 linux_sendmsg_common(struct thread *td, l_int s, struct l_msghdr *msghdr,
1341 l_uint flags)
1342 {
1343 struct cmsghdr *cmsg;
1344 struct mbuf *control;
1345 struct msghdr msg;
1346 struct l_cmsghdr linux_cmsg;
1347 struct l_cmsghdr *ptr_cmsg;
1348 struct l_msghdr linux_msghdr;
1349 struct iovec *iov;
1350 socklen_t datalen;
1351 struct sockaddr *sa;
1352 struct socket *so;
1353 sa_family_t sa_family;
1354 struct file *fp;
1355 void *data;
1356 l_size_t len;
1357 l_size_t clen;
1358 int error, fflag;
1359
1360 error = copyin(msghdr, &linux_msghdr, sizeof(linux_msghdr));
1361 if (error != 0)
1362 return (error);
1363
1364 /*
1365 * Some Linux applications (ping) define a non-NULL control data
1366 * pointer, but a msg_controllen of 0, which is not allowed in the
1367 * FreeBSD system call interface. NULL the msg_control pointer in
1368 * order to handle this case. This should be checked, but allows the
1369 * Linux ping to work.
1370 */
1371 if (PTRIN(linux_msghdr.msg_control) != NULL &&
1372 linux_msghdr.msg_controllen == 0)
1373 linux_msghdr.msg_control = PTROUT(NULL);
1374
1375 error = linux_to_bsd_msghdr(&msg, &linux_msghdr);
1376 if (error != 0)
1377 return (error);
1378
1379 #ifdef COMPAT_LINUX32
1380 error = linux32_copyiniov(PTRIN(msg.msg_iov), msg.msg_iovlen,
1381 &iov, EMSGSIZE);
1382 #else
1383 error = copyiniov(msg.msg_iov, msg.msg_iovlen, &iov, EMSGSIZE);
1384 #endif
1385 if (error != 0)
1386 return (error);
1387
1388 control = NULL;
1389
1390 error = kern_getsockname(td, s, &sa, &datalen);
1391 if (error != 0)
1392 goto bad;
1393 sa_family = sa->sa_family;
1394 free(sa, M_SONAME);
1395
1396 if (flags & LINUX_MSG_OOB) {
1397 error = EOPNOTSUPP;
1398 if (sa_family == AF_UNIX)
1399 goto bad;
1400
1401 error = getsock_cap(td, s, &cap_send_rights, &fp,
1402 &fflag, NULL);
1403 if (error != 0)
1404 goto bad;
1405 so = fp->f_data;
1406 if (so->so_type != SOCK_STREAM)
1407 error = EOPNOTSUPP;
1408 fdrop(fp, td);
1409 if (error != 0)
1410 goto bad;
1411 }
1412
1413 if (linux_msghdr.msg_controllen >= sizeof(struct l_cmsghdr)) {
1414 error = ENOBUFS;
1415 control = m_get(M_WAITOK, MT_CONTROL);
1416 MCLGET(control, M_WAITOK);
1417 data = mtod(control, void *);
1418 datalen = 0;
1419
1420 ptr_cmsg = PTRIN(linux_msghdr.msg_control);
1421 clen = linux_msghdr.msg_controllen;
1422 do {
1423 error = copyin(ptr_cmsg, &linux_cmsg,
1424 sizeof(struct l_cmsghdr));
1425 if (error != 0)
1426 goto bad;
1427
1428 error = EINVAL;
1429 if (linux_cmsg.cmsg_len < sizeof(struct l_cmsghdr) ||
1430 linux_cmsg.cmsg_len > clen)
1431 goto bad;
1432
1433 if (datalen + CMSG_HDRSZ > MCLBYTES)
1434 goto bad;
1435
1436 /*
1437 * Now we support only SCM_RIGHTS and SCM_CRED,
1438 * so return EINVAL in any other cmsg_type
1439 */
1440 cmsg = data;
1441 cmsg->cmsg_type =
1442 linux_to_bsd_cmsg_type(linux_cmsg.cmsg_type);
1443 cmsg->cmsg_level =
1444 linux_to_bsd_sockopt_level(linux_cmsg.cmsg_level);
1445 if (cmsg->cmsg_type == -1
1446 || cmsg->cmsg_level != SOL_SOCKET) {
1447 linux_msg(curthread,
1448 "unsupported sendmsg cmsg level %d type %d",
1449 linux_cmsg.cmsg_level, linux_cmsg.cmsg_type);
1450 goto bad;
1451 }
1452
1453 /*
1454 * Some applications (e.g. pulseaudio) attempt to
1455 * send ancillary data even if the underlying protocol
1456 * doesn't support it which is not allowed in the
1457 * FreeBSD system call interface.
1458 */
1459 if (sa_family != AF_UNIX)
1460 goto next;
1461
1462 if (cmsg->cmsg_type == SCM_CREDS) {
1463 len = sizeof(struct cmsgcred);
1464 if (datalen + CMSG_SPACE(len) > MCLBYTES)
1465 goto bad;
1466
1467 /*
1468 * The lower levels will fill in the structure
1469 */
1470 memset(CMSG_DATA(data), 0, len);
1471 } else {
1472 len = linux_cmsg.cmsg_len - L_CMSG_HDRSZ;
1473 if (datalen + CMSG_SPACE(len) < datalen ||
1474 datalen + CMSG_SPACE(len) > MCLBYTES)
1475 goto bad;
1476
1477 error = copyin(LINUX_CMSG_DATA(ptr_cmsg),
1478 CMSG_DATA(data), len);
1479 if (error != 0)
1480 goto bad;
1481 }
1482
1483 cmsg->cmsg_len = CMSG_LEN(len);
1484 data = (char *)data + CMSG_SPACE(len);
1485 datalen += CMSG_SPACE(len);
1486
1487 next:
1488 if (clen <= LINUX_CMSG_ALIGN(linux_cmsg.cmsg_len))
1489 break;
1490
1491 clen -= LINUX_CMSG_ALIGN(linux_cmsg.cmsg_len);
1492 ptr_cmsg = (struct l_cmsghdr *)((char *)ptr_cmsg +
1493 LINUX_CMSG_ALIGN(linux_cmsg.cmsg_len));
1494 } while(clen >= sizeof(struct l_cmsghdr));
1495
1496 control->m_len = datalen;
1497 if (datalen == 0) {
1498 m_freem(control);
1499 control = NULL;
1500 }
1501 }
1502
1503 msg.msg_iov = iov;
1504 msg.msg_flags = 0;
1505 error = linux_sendit(td, s, &msg, flags, control, UIO_USERSPACE);
1506 control = NULL;
1507
1508 bad:
1509 m_freem(control);
1510 free(iov, M_IOV);
1511 return (error);
1512 }
1513
1514 int
linux_sendmsg(struct thread * td,struct linux_sendmsg_args * args)1515 linux_sendmsg(struct thread *td, struct linux_sendmsg_args *args)
1516 {
1517
1518 return (linux_sendmsg_common(td, args->s, PTRIN(args->msg),
1519 args->flags));
1520 }
1521
1522 int
linux_sendmmsg(struct thread * td,struct linux_sendmmsg_args * args)1523 linux_sendmmsg(struct thread *td, struct linux_sendmmsg_args *args)
1524 {
1525 struct l_mmsghdr *msg;
1526 l_uint retval;
1527 int error, datagrams;
1528
1529 if (args->vlen > UIO_MAXIOV)
1530 args->vlen = UIO_MAXIOV;
1531
1532 msg = PTRIN(args->msg);
1533 datagrams = 0;
1534 while (datagrams < args->vlen) {
1535 error = linux_sendmsg_common(td, args->s, &msg->msg_hdr,
1536 args->flags);
1537 if (error != 0)
1538 break;
1539
1540 retval = td->td_retval[0];
1541 error = copyout(&retval, &msg->msg_len, sizeof(msg->msg_len));
1542 if (error != 0)
1543 break;
1544 ++msg;
1545 ++datagrams;
1546 }
1547 if (error == 0)
1548 td->td_retval[0] = datagrams;
1549 return (error);
1550 }
1551
1552 static int
recvmsg_scm_rights(struct thread * td,l_uint flags,socklen_t * datalen,void ** data,void ** udata)1553 recvmsg_scm_rights(struct thread *td, l_uint flags, socklen_t *datalen,
1554 void **data, void **udata)
1555 {
1556 int i, fd, fds, *fdp;
1557
1558 if (flags & LINUX_MSG_CMSG_CLOEXEC) {
1559 fds = *datalen / sizeof(int);
1560 fdp = *data;
1561 for (i = 0; i < fds; i++) {
1562 fd = *fdp++;
1563 (void)kern_fcntl(td, fd, F_SETFD, FD_CLOEXEC);
1564 }
1565 }
1566 return (0);
1567 }
1568
1569
1570 static int
recvmsg_scm_creds(socklen_t * datalen,void ** data,void ** udata)1571 recvmsg_scm_creds(socklen_t *datalen, void **data, void **udata)
1572 {
1573 struct cmsgcred *cmcred;
1574 struct l_ucred lu;
1575
1576 cmcred = *data;
1577 lu.pid = cmcred->cmcred_pid;
1578 lu.uid = cmcred->cmcred_uid;
1579 lu.gid = cmcred->cmcred_gid;
1580 memmove(*data, &lu, sizeof(lu));
1581 *datalen = sizeof(lu);
1582 return (0);
1583 }
1584 _Static_assert(sizeof(struct cmsgcred) >= sizeof(struct l_ucred),
1585 "scm_creds sizeof l_ucred");
1586
1587 static int
recvmsg_scm_creds2(socklen_t * datalen,void ** data,void ** udata)1588 recvmsg_scm_creds2(socklen_t *datalen, void **data, void **udata)
1589 {
1590 struct sockcred2 *scred;
1591 struct l_ucred lu;
1592
1593 scred = *data;
1594 lu.pid = scred->sc_pid;
1595 lu.uid = scred->sc_uid;
1596 lu.gid = scred->sc_gid;
1597 memmove(*data, &lu, sizeof(lu));
1598 *datalen = sizeof(lu);
1599 return (0);
1600 }
1601 _Static_assert(sizeof(struct sockcred2) >= sizeof(struct l_ucred),
1602 "scm_creds2 sizeof l_ucred");
1603
1604 #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32))
1605 static int
recvmsg_scm_timestamp(l_int msg_type,socklen_t * datalen,void ** data,void ** udata)1606 recvmsg_scm_timestamp(l_int msg_type, socklen_t *datalen, void **data,
1607 void **udata)
1608 {
1609 l_sock_timeval ltv64;
1610 l_timeval ltv;
1611 struct timeval *tv;
1612 socklen_t len;
1613 void *buf;
1614
1615 if (*datalen != sizeof(struct timeval))
1616 return (EMSGSIZE);
1617
1618 tv = *data;
1619 #if defined(COMPAT_LINUX32)
1620 if (msg_type == LINUX_SCM_TIMESTAMPO &&
1621 (tv->tv_sec > INT_MAX || tv->tv_sec < INT_MIN))
1622 return (EOVERFLOW);
1623 #endif
1624 if (msg_type == LINUX_SCM_TIMESTAMPN)
1625 len = sizeof(ltv64);
1626 else
1627 len = sizeof(ltv);
1628
1629 buf = malloc(len, M_LINUX, M_WAITOK);
1630 if (msg_type == LINUX_SCM_TIMESTAMPN) {
1631 ltv64.tv_sec = tv->tv_sec;
1632 ltv64.tv_usec = tv->tv_usec;
1633 memmove(buf, <v64, len);
1634 } else {
1635 ltv.tv_sec = tv->tv_sec;
1636 ltv.tv_usec = tv->tv_usec;
1637 memmove(buf, <v, len);
1638 }
1639 *data = *udata = buf;
1640 *datalen = len;
1641 return (0);
1642 }
1643 #else
1644 _Static_assert(sizeof(struct timeval) == sizeof(l_timeval),
1645 "scm_timestamp sizeof l_timeval");
1646 #endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */
1647
1648 #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32))
1649 static int
recvmsg_scm_timestampns(l_int msg_type,socklen_t * datalen,void ** data,void ** udata)1650 recvmsg_scm_timestampns(l_int msg_type, socklen_t *datalen, void **data,
1651 void **udata)
1652 {
1653 struct l_timespec64 ts64;
1654 struct l_timespec ts32;
1655 struct timespec ts;
1656 socklen_t len;
1657 void *buf;
1658
1659 if (msg_type == LINUX_SCM_TIMESTAMPNSO)
1660 len = sizeof(ts32);
1661 else
1662 len = sizeof(ts64);
1663
1664 buf = malloc(len, M_LINUX, M_WAITOK);
1665 bintime2timespec(*data, &ts);
1666 if (msg_type == LINUX_SCM_TIMESTAMPNSO) {
1667 ts32.tv_sec = ts.tv_sec;
1668 ts32.tv_nsec = ts.tv_nsec;
1669 memmove(buf, &ts32, len);
1670 } else {
1671 ts64.tv_sec = ts.tv_sec;
1672 ts64.tv_nsec = ts.tv_nsec;
1673 memmove(buf, &ts64, len);
1674 }
1675 *data = *udata = buf;
1676 *datalen = len;
1677 return (0);
1678 }
1679 #else
1680 static int
recvmsg_scm_timestampns(l_int msg_type,socklen_t * datalen,void ** data,void ** udata)1681 recvmsg_scm_timestampns(l_int msg_type, socklen_t *datalen, void **data,
1682 void **udata)
1683 {
1684 struct timespec ts;
1685
1686 bintime2timespec(*data, &ts);
1687 memmove(*data, &ts, sizeof(struct timespec));
1688 *datalen = sizeof(struct timespec);
1689 return (0);
1690 }
1691 _Static_assert(sizeof(struct bintime) >= sizeof(struct timespec),
1692 "scm_timestampns sizeof timespec");
1693 #endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */
1694
1695 static int
recvmsg_scm_sol_socket(struct thread * td,l_int msg_type,l_int lmsg_type,l_uint flags,socklen_t * datalen,void ** data,void ** udata)1696 recvmsg_scm_sol_socket(struct thread *td, l_int msg_type, l_int lmsg_type,
1697 l_uint flags, socklen_t *datalen, void **data, void **udata)
1698 {
1699 int error;
1700
1701 error = 0;
1702 switch (msg_type) {
1703 case SCM_RIGHTS:
1704 error = recvmsg_scm_rights(td, flags, datalen,
1705 data, udata);
1706 break;
1707 case SCM_CREDS:
1708 error = recvmsg_scm_creds(datalen, data, udata);
1709 break;
1710 case SCM_CREDS2:
1711 error = recvmsg_scm_creds2(datalen, data, udata);
1712 break;
1713 case SCM_TIMESTAMP:
1714 #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32))
1715 error = recvmsg_scm_timestamp(lmsg_type, datalen,
1716 data, udata);
1717 #endif
1718 break;
1719 case SCM_BINTIME:
1720 error = recvmsg_scm_timestampns(lmsg_type, datalen,
1721 data, udata);
1722 break;
1723 }
1724
1725 return (error);
1726 }
1727
1728 static int
recvmsg_scm_ip_origdstaddr(socklen_t * datalen,void ** data,void ** udata)1729 recvmsg_scm_ip_origdstaddr(socklen_t *datalen, void **data, void **udata)
1730 {
1731 struct l_sockaddr *lsa;
1732 int error;
1733
1734 error = bsd_to_linux_sockaddr(*data, &lsa, *datalen);
1735 if (error == 0) {
1736 *data = *udata = lsa;
1737 *datalen = sizeof(*lsa);
1738 }
1739 return (error);
1740 }
1741
1742 static int
recvmsg_scm_ipproto_ip(l_int msg_type,l_int lmsg_type,socklen_t * datalen,void ** data,void ** udata)1743 recvmsg_scm_ipproto_ip(l_int msg_type, l_int lmsg_type, socklen_t *datalen,
1744 void **data, void **udata)
1745 {
1746 int error;
1747
1748 error = 0;
1749 switch (msg_type) {
1750 case IP_ORIGDSTADDR:
1751 error = recvmsg_scm_ip_origdstaddr(datalen, data,
1752 udata);
1753 break;
1754 }
1755
1756 return (error);
1757 }
1758
1759 static int
linux_recvmsg_common(struct thread * td,l_int s,struct l_msghdr * msghdr,l_uint flags,struct msghdr * msg)1760 linux_recvmsg_common(struct thread *td, l_int s, struct l_msghdr *msghdr,
1761 l_uint flags, struct msghdr *msg)
1762 {
1763 struct proc *p = td->td_proc;
1764 struct cmsghdr *cm;
1765 struct l_cmsghdr *lcm = NULL;
1766 socklen_t datalen, maxlen, outlen;
1767 struct l_msghdr l_msghdr;
1768 struct iovec *iov, *uiov;
1769 struct mbuf *m, *control = NULL;
1770 struct mbuf **controlp;
1771 struct sockaddr *sa;
1772 caddr_t outbuf;
1773 void *data, *udata;
1774 int error, skiped;
1775
1776 error = copyin(msghdr, &l_msghdr, sizeof(l_msghdr));
1777 if (error != 0)
1778 return (error);
1779
1780 /*
1781 * Pass user-supplied recvmsg() flags in msg_flags field,
1782 * following sys_recvmsg() convention.
1783 */
1784 l_msghdr.msg_flags = flags;
1785
1786 error = linux_to_bsd_msghdr(msg, &l_msghdr);
1787 if (error != 0)
1788 return (error);
1789
1790 #ifdef COMPAT_LINUX32
1791 error = linux32_copyiniov(PTRIN(msg->msg_iov), msg->msg_iovlen,
1792 &iov, EMSGSIZE);
1793 #else
1794 error = copyiniov(msg->msg_iov, msg->msg_iovlen, &iov, EMSGSIZE);
1795 #endif
1796 if (error != 0)
1797 return (error);
1798
1799 if (msg->msg_name != NULL && msg->msg_namelen > 0) {
1800 msg->msg_namelen = min(msg->msg_namelen, SOCK_MAXADDRLEN);
1801 sa = malloc(msg->msg_namelen, M_SONAME, M_WAITOK);
1802 msg->msg_name = sa;
1803 } else {
1804 sa = NULL;
1805 msg->msg_name = NULL;
1806 }
1807
1808 uiov = msg->msg_iov;
1809 msg->msg_iov = iov;
1810 controlp = (msg->msg_control != NULL) ? &control : NULL;
1811 error = kern_recvit(td, s, msg, UIO_SYSSPACE, controlp);
1812 msg->msg_iov = uiov;
1813 if (error != 0)
1814 goto bad;
1815
1816 /*
1817 * Note that kern_recvit() updates msg->msg_namelen.
1818 */
1819 if (msg->msg_name != NULL && msg->msg_namelen > 0) {
1820 msg->msg_name = PTRIN(l_msghdr.msg_name);
1821 error = linux_copyout_sockaddr(sa, msg->msg_name,
1822 msg->msg_namelen);
1823 if (error != 0)
1824 goto bad;
1825 }
1826
1827 error = bsd_to_linux_msghdr(msg, &l_msghdr);
1828 if (error != 0)
1829 goto bad;
1830
1831 skiped = outlen = 0;
1832 maxlen = l_msghdr.msg_controllen;
1833 if (control == NULL)
1834 goto out;
1835
1836 lcm = malloc(L_CMSG_HDRSZ, M_LINUX, M_WAITOK | M_ZERO);
1837 msg->msg_control = mtod(control, struct cmsghdr *);
1838 msg->msg_controllen = control->m_len;
1839 outbuf = PTRIN(l_msghdr.msg_control);
1840 for (m = control; m != NULL; m = m->m_next) {
1841 cm = mtod(m, struct cmsghdr *);
1842 lcm->cmsg_type = bsd_to_linux_cmsg_type(p, cm->cmsg_type,
1843 cm->cmsg_level);
1844 lcm->cmsg_level = bsd_to_linux_sockopt_level(cm->cmsg_level);
1845
1846 if (lcm->cmsg_type == -1 ||
1847 cm->cmsg_level == -1) {
1848 LINUX_RATELIMIT_MSG_OPT2(
1849 "unsupported recvmsg cmsg level %d type %d",
1850 cm->cmsg_level, cm->cmsg_type);
1851 /* Skip unsupported messages */
1852 skiped++;
1853 continue;
1854 }
1855 data = CMSG_DATA(cm);
1856 datalen = (caddr_t)cm + cm->cmsg_len - (caddr_t)data;
1857 udata = NULL;
1858 error = 0;
1859
1860 switch (cm->cmsg_level) {
1861 case IPPROTO_IP:
1862 error = recvmsg_scm_ipproto_ip(cm->cmsg_type,
1863 lcm->cmsg_type, &datalen, &data, &udata);
1864 break;
1865 case SOL_SOCKET:
1866 error = recvmsg_scm_sol_socket(td, cm->cmsg_type,
1867 lcm->cmsg_type, flags, &datalen, &data, &udata);
1868 break;
1869 }
1870
1871 /* The recvmsg_scm_ is responsible to free udata on error. */
1872 if (error != 0)
1873 goto bad;
1874
1875 if (outlen + LINUX_CMSG_LEN(datalen) > maxlen) {
1876 if (outlen == 0) {
1877 error = EMSGSIZE;
1878 goto err;
1879 } else {
1880 l_msghdr.msg_flags |= LINUX_MSG_CTRUNC;
1881 m_dispose_extcontrolm(control);
1882 free(udata, M_LINUX);
1883 goto out;
1884 }
1885 }
1886
1887 lcm->cmsg_len = LINUX_CMSG_LEN(datalen);
1888 error = copyout(lcm, outbuf, L_CMSG_HDRSZ);
1889 if (error == 0) {
1890 error = copyout(data, LINUX_CMSG_DATA(outbuf), datalen);
1891 if (error == 0) {
1892 outbuf += LINUX_CMSG_SPACE(datalen);
1893 outlen += LINUX_CMSG_SPACE(datalen);
1894 }
1895 }
1896 err:
1897 free(udata, M_LINUX);
1898 if (error != 0)
1899 goto bad;
1900 }
1901 if (outlen == 0 && skiped > 0) {
1902 error = EINVAL;
1903 goto bad;
1904 }
1905
1906 out:
1907 l_msghdr.msg_controllen = outlen;
1908 error = copyout(&l_msghdr, msghdr, sizeof(l_msghdr));
1909
1910 bad:
1911 if (control != NULL) {
1912 if (error != 0)
1913 m_dispose_extcontrolm(control);
1914 m_freem(control);
1915 }
1916 free(iov, M_IOV);
1917 free(lcm, M_LINUX);
1918 free(sa, M_SONAME);
1919
1920 return (error);
1921 }
1922
1923 int
linux_recvmsg(struct thread * td,struct linux_recvmsg_args * args)1924 linux_recvmsg(struct thread *td, struct linux_recvmsg_args *args)
1925 {
1926 struct msghdr bsd_msg;
1927 struct file *fp;
1928 int error;
1929
1930 error = getsock_cap(td, args->s, &cap_recv_rights,
1931 &fp, NULL, NULL);
1932 if (error != 0)
1933 return (error);
1934 fdrop(fp, td);
1935 return (linux_recvmsg_common(td, args->s, PTRIN(args->msg),
1936 args->flags, &bsd_msg));
1937 }
1938
1939 static int
linux_recvmmsg_common(struct thread * td,l_int s,struct l_mmsghdr * msg,l_uint vlen,l_uint flags,struct timespec * tts)1940 linux_recvmmsg_common(struct thread *td, l_int s, struct l_mmsghdr *msg,
1941 l_uint vlen, l_uint flags, struct timespec *tts)
1942 {
1943 struct msghdr bsd_msg;
1944 struct timespec ts;
1945 struct file *fp;
1946 l_uint retval;
1947 int error, datagrams;
1948
1949 error = getsock_cap(td, s, &cap_recv_rights,
1950 &fp, NULL, NULL);
1951 if (error != 0)
1952 return (error);
1953 datagrams = 0;
1954 while (datagrams < vlen) {
1955 error = linux_recvmsg_common(td, s, &msg->msg_hdr,
1956 flags & ~LINUX_MSG_WAITFORONE, &bsd_msg);
1957 if (error != 0)
1958 break;
1959
1960 retval = td->td_retval[0];
1961 error = copyout(&retval, &msg->msg_len, sizeof(msg->msg_len));
1962 if (error != 0)
1963 break;
1964 ++msg;
1965 ++datagrams;
1966
1967 /*
1968 * MSG_WAITFORONE turns on MSG_DONTWAIT after one packet.
1969 */
1970 if (flags & LINUX_MSG_WAITFORONE)
1971 flags |= LINUX_MSG_DONTWAIT;
1972
1973 /*
1974 * See BUGS section of recvmmsg(2).
1975 */
1976 if (tts) {
1977 getnanotime(&ts);
1978 timespecsub(&ts, tts, &ts);
1979 if (!timespecisset(&ts) || ts.tv_sec > 0)
1980 break;
1981 }
1982 /* Out of band data, return right away. */
1983 if (bsd_msg.msg_flags & MSG_OOB)
1984 break;
1985 }
1986 if (error == 0)
1987 td->td_retval[0] = datagrams;
1988 fdrop(fp, td);
1989 return (error);
1990 }
1991
1992 int
linux_recvmmsg(struct thread * td,struct linux_recvmmsg_args * args)1993 linux_recvmmsg(struct thread *td, struct linux_recvmmsg_args *args)
1994 {
1995 struct timespec ts, tts, *ptts;
1996 int error;
1997
1998 if (args->timeout) {
1999 error = linux_get_timespec(&ts, args->timeout);
2000 if (error != 0)
2001 return (error);
2002 getnanotime(&tts);
2003 timespecadd(&tts, &ts, &tts);
2004 ptts = &tts;
2005 }
2006 else ptts = NULL;
2007
2008 return (linux_recvmmsg_common(td, args->s, PTRIN(args->msg),
2009 args->vlen, args->flags, ptts));
2010 }
2011
2012 #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32))
2013 int
linux_recvmmsg_time64(struct thread * td,struct linux_recvmmsg_time64_args * args)2014 linux_recvmmsg_time64(struct thread *td, struct linux_recvmmsg_time64_args *args)
2015 {
2016 struct timespec ts, tts, *ptts;
2017 int error;
2018
2019 if (args->timeout) {
2020 error = linux_get_timespec64(&ts, args->timeout);
2021 if (error != 0)
2022 return (error);
2023 getnanotime(&tts);
2024 timespecadd(&tts, &ts, &tts);
2025 ptts = &tts;
2026 }
2027 else ptts = NULL;
2028
2029 return (linux_recvmmsg_common(td, args->s, PTRIN(args->msg),
2030 args->vlen, args->flags, ptts));
2031 }
2032 #endif
2033
2034 int
linux_shutdown(struct thread * td,struct linux_shutdown_args * args)2035 linux_shutdown(struct thread *td, struct linux_shutdown_args *args)
2036 {
2037
2038 return (kern_shutdown(td, args->s, args->how));
2039 }
2040
2041 int
linux_setsockopt(struct thread * td,struct linux_setsockopt_args * args)2042 linux_setsockopt(struct thread *td, struct linux_setsockopt_args *args)
2043 {
2044 struct proc *p = td->td_proc;
2045 struct linux_pemuldata *pem;
2046 l_timeval linux_tv;
2047 struct sockaddr *sa;
2048 struct timeval tv;
2049 socklen_t len;
2050 int error, level, name, val;
2051
2052 level = linux_to_bsd_sockopt_level(args->level);
2053 switch (level) {
2054 case SOL_SOCKET:
2055 name = linux_to_bsd_so_sockopt(args->optname);
2056 switch (name) {
2057 case LOCAL_CREDS_PERSISTENT:
2058 level = SOL_LOCAL;
2059 break;
2060 case SO_RCVTIMEO:
2061 /* FALLTHROUGH */
2062 case SO_SNDTIMEO:
2063 error = copyin(PTRIN(args->optval), &linux_tv,
2064 sizeof(linux_tv));
2065 if (error != 0)
2066 return (error);
2067 tv.tv_sec = linux_tv.tv_sec;
2068 tv.tv_usec = linux_tv.tv_usec;
2069 return (kern_setsockopt(td, args->s, level,
2070 name, &tv, UIO_SYSSPACE, sizeof(tv)));
2071 /* NOTREACHED */
2072 case SO_TIMESTAMP:
2073 /* overwrite SO_BINTIME */
2074 val = 0;
2075 error = kern_setsockopt(td, args->s, level,
2076 SO_BINTIME, &val, UIO_SYSSPACE, sizeof(val));
2077 if (error != 0)
2078 return (error);
2079 pem = pem_find(p);
2080 pem->so_timestamp = args->optname;
2081 break;
2082 case SO_BINTIME:
2083 /* overwrite SO_TIMESTAMP */
2084 val = 0;
2085 error = kern_setsockopt(td, args->s, level,
2086 SO_TIMESTAMP, &val, UIO_SYSSPACE, sizeof(val));
2087 if (error != 0)
2088 return (error);
2089 pem = pem_find(p);
2090 pem->so_timestampns = args->optname;
2091 break;
2092 default:
2093 break;
2094 }
2095 break;
2096 case IPPROTO_IP:
2097 if (args->optname == LINUX_IP_RECVERR &&
2098 linux_ignore_ip_recverr) {
2099 /*
2100 * XXX: This is a hack to unbreak DNS resolution
2101 * with glibc 2.30 and above.
2102 */
2103 return (0);
2104 }
2105 name = linux_to_bsd_ip_sockopt(args->optname);
2106 break;
2107 case IPPROTO_IPV6:
2108 name = linux_to_bsd_ip6_sockopt(args->optname);
2109 break;
2110 case IPPROTO_TCP:
2111 name = linux_to_bsd_tcp_sockopt(args->optname);
2112 break;
2113 case SOL_NETLINK:
2114 level = SOL_SOCKET;
2115 name = args->optname;
2116 break;
2117 default:
2118 name = -1;
2119 break;
2120 }
2121 if (name < 0) {
2122 if (name == -1)
2123 linux_msg(curthread,
2124 "unsupported setsockopt level %d optname %d",
2125 args->level, args->optname);
2126 return (ENOPROTOOPT);
2127 }
2128
2129 if (name == IPV6_NEXTHOP) {
2130 len = args->optlen;
2131 error = linux_to_bsd_sockaddr(PTRIN(args->optval), &sa, &len);
2132 if (error != 0)
2133 return (error);
2134
2135 error = kern_setsockopt(td, args->s, level,
2136 name, sa, UIO_SYSSPACE, len);
2137 free(sa, M_SONAME);
2138 } else {
2139 error = kern_setsockopt(td, args->s, level,
2140 name, PTRIN(args->optval), UIO_USERSPACE, args->optlen);
2141 }
2142
2143 return (error);
2144 }
2145
2146 static int
linux_sockopt_copyout(struct thread * td,void * val,socklen_t len,struct linux_getsockopt_args * args)2147 linux_sockopt_copyout(struct thread *td, void *val, socklen_t len,
2148 struct linux_getsockopt_args *args)
2149 {
2150 int error;
2151
2152 error = copyout(val, PTRIN(args->optval), len);
2153 if (error == 0)
2154 error = copyout(&len, PTRIN(args->optlen), sizeof(len));
2155 return (error);
2156 }
2157
2158 static int
linux_getsockopt_so_peergroups(struct thread * td,struct linux_getsockopt_args * args)2159 linux_getsockopt_so_peergroups(struct thread *td,
2160 struct linux_getsockopt_args *args)
2161 {
2162 struct xucred xu;
2163 socklen_t xulen, len;
2164 int error, i;
2165
2166 xulen = sizeof(xu);
2167 error = kern_getsockopt(td, args->s, 0,
2168 LOCAL_PEERCRED, &xu, UIO_SYSSPACE, &xulen);
2169 if (error != 0)
2170 return (error);
2171
2172 len = xu.cr_ngroups * sizeof(l_gid_t);
2173 if (args->optlen < len) {
2174 error = copyout(&len, PTRIN(args->optlen), sizeof(len));
2175 if (error == 0)
2176 error = ERANGE;
2177 return (error);
2178 }
2179
2180 /*
2181 * "- 1" to skip the primary group.
2182 */
2183 for (i = 0; i < xu.cr_ngroups - 1; i++) {
2184 error = copyout(xu.cr_groups + i + 1,
2185 (void *)(args->optval + i * sizeof(l_gid_t)),
2186 sizeof(l_gid_t));
2187 if (error != 0)
2188 return (error);
2189 }
2190
2191 error = copyout(&len, PTRIN(args->optlen), sizeof(len));
2192 return (error);
2193 }
2194
2195 static int
linux_getsockopt_so_peersec(struct thread * td,struct linux_getsockopt_args * args)2196 linux_getsockopt_so_peersec(struct thread *td,
2197 struct linux_getsockopt_args *args)
2198 {
2199 socklen_t len;
2200 int error;
2201
2202 len = sizeof(SECURITY_CONTEXT_STRING);
2203 if (args->optlen < len) {
2204 error = copyout(&len, PTRIN(args->optlen), sizeof(len));
2205 if (error == 0)
2206 error = ERANGE;
2207 return (error);
2208 }
2209
2210 return (linux_sockopt_copyout(td, SECURITY_CONTEXT_STRING,
2211 len, args));
2212 }
2213
2214 static int
linux_getsockopt_so_linger(struct thread * td,struct linux_getsockopt_args * args)2215 linux_getsockopt_so_linger(struct thread *td,
2216 struct linux_getsockopt_args *args)
2217 {
2218 struct linger ling;
2219 socklen_t len;
2220 int error;
2221
2222 len = sizeof(ling);
2223 error = kern_getsockopt(td, args->s, SOL_SOCKET,
2224 SO_LINGER, &ling, UIO_SYSSPACE, &len);
2225 if (error != 0)
2226 return (error);
2227 ling.l_onoff = ((ling.l_onoff & SO_LINGER) != 0);
2228 return (linux_sockopt_copyout(td, &ling, len, args));
2229 }
2230
2231 int
linux_getsockopt(struct thread * td,struct linux_getsockopt_args * args)2232 linux_getsockopt(struct thread *td, struct linux_getsockopt_args *args)
2233 {
2234 l_timeval linux_tv;
2235 struct timeval tv;
2236 socklen_t tv_len, xulen, len;
2237 struct sockaddr *sa;
2238 struct xucred xu;
2239 struct l_ucred lxu;
2240 int error, level, name, newval;
2241
2242 level = linux_to_bsd_sockopt_level(args->level);
2243 switch (level) {
2244 case SOL_SOCKET:
2245 switch (args->optname) {
2246 case LINUX_SO_PEERGROUPS:
2247 return (linux_getsockopt_so_peergroups(td, args));
2248 case LINUX_SO_PEERSEC:
2249 return (linux_getsockopt_so_peersec(td, args));
2250 default:
2251 break;
2252 }
2253
2254 name = linux_to_bsd_so_sockopt(args->optname);
2255 switch (name) {
2256 case LOCAL_CREDS_PERSISTENT:
2257 level = SOL_LOCAL;
2258 break;
2259 case SO_RCVTIMEO:
2260 /* FALLTHROUGH */
2261 case SO_SNDTIMEO:
2262 tv_len = sizeof(tv);
2263 error = kern_getsockopt(td, args->s, level,
2264 name, &tv, UIO_SYSSPACE, &tv_len);
2265 if (error != 0)
2266 return (error);
2267 linux_tv.tv_sec = tv.tv_sec;
2268 linux_tv.tv_usec = tv.tv_usec;
2269 return (linux_sockopt_copyout(td, &linux_tv,
2270 sizeof(linux_tv), args));
2271 /* NOTREACHED */
2272 case LOCAL_PEERCRED:
2273 if (args->optlen < sizeof(lxu))
2274 return (EINVAL);
2275 /*
2276 * LOCAL_PEERCRED is not served at the SOL_SOCKET level,
2277 * but by the Unix socket's level 0.
2278 */
2279 level = 0;
2280 xulen = sizeof(xu);
2281 error = kern_getsockopt(td, args->s, level,
2282 name, &xu, UIO_SYSSPACE, &xulen);
2283 if (error != 0)
2284 return (error);
2285 lxu.pid = xu.cr_pid;
2286 lxu.uid = xu.cr_uid;
2287 lxu.gid = xu.cr_gid;
2288 return (linux_sockopt_copyout(td, &lxu,
2289 sizeof(lxu), args));
2290 /* NOTREACHED */
2291 case SO_ERROR:
2292 len = sizeof(newval);
2293 error = kern_getsockopt(td, args->s, level,
2294 name, &newval, UIO_SYSSPACE, &len);
2295 if (error != 0)
2296 return (error);
2297 newval = -bsd_to_linux_errno(newval);
2298 return (linux_sockopt_copyout(td, &newval,
2299 len, args));
2300 /* NOTREACHED */
2301 case SO_DOMAIN:
2302 len = sizeof(newval);
2303 error = kern_getsockopt(td, args->s, level,
2304 name, &newval, UIO_SYSSPACE, &len);
2305 if (error != 0)
2306 return (error);
2307 newval = bsd_to_linux_domain(newval);
2308 if (newval == -1)
2309 return (ENOPROTOOPT);
2310 return (linux_sockopt_copyout(td, &newval,
2311 len, args));
2312 /* NOTREACHED */
2313 case SO_LINGER:
2314 return (linux_getsockopt_so_linger(td, args));
2315 /* NOTREACHED */
2316 default:
2317 break;
2318 }
2319 break;
2320 case IPPROTO_IP:
2321 name = linux_to_bsd_ip_sockopt(args->optname);
2322 break;
2323 case IPPROTO_IPV6:
2324 name = linux_to_bsd_ip6_sockopt(args->optname);
2325 break;
2326 case IPPROTO_TCP:
2327 name = linux_to_bsd_tcp_sockopt(args->optname);
2328 break;
2329 default:
2330 name = -1;
2331 break;
2332 }
2333 if (name < 0) {
2334 if (name == -1)
2335 linux_msg(curthread,
2336 "unsupported getsockopt level %d optname %d",
2337 args->level, args->optname);
2338 return (EINVAL);
2339 }
2340
2341 if (name == IPV6_NEXTHOP) {
2342 error = copyin(PTRIN(args->optlen), &len, sizeof(len));
2343 if (error != 0)
2344 return (error);
2345 sa = malloc(len, M_SONAME, M_WAITOK);
2346
2347 error = kern_getsockopt(td, args->s, level,
2348 name, sa, UIO_SYSSPACE, &len);
2349 if (error != 0)
2350 goto out;
2351
2352 error = linux_copyout_sockaddr(sa, PTRIN(args->optval), len);
2353 if (error == 0)
2354 error = copyout(&len, PTRIN(args->optlen),
2355 sizeof(len));
2356 out:
2357 free(sa, M_SONAME);
2358 } else {
2359 if (args->optval) {
2360 error = copyin(PTRIN(args->optlen), &len, sizeof(len));
2361 if (error != 0)
2362 return (error);
2363 }
2364 error = kern_getsockopt(td, args->s, level,
2365 name, PTRIN(args->optval), UIO_USERSPACE, &len);
2366 if (error == 0)
2367 error = copyout(&len, PTRIN(args->optlen),
2368 sizeof(len));
2369 }
2370
2371 return (error);
2372 }
2373
2374 static int
linux_sendfile_common(struct thread * td,l_int out,l_int in,l_loff_t * offset,l_size_t count)2375 linux_sendfile_common(struct thread *td, l_int out, l_int in,
2376 l_loff_t *offset, l_size_t count)
2377 {
2378 off_t bytes_read;
2379 int error;
2380 l_loff_t current_offset;
2381 struct file *fp;
2382
2383 AUDIT_ARG_FD(in);
2384 error = fget_read(td, in, &cap_pread_rights, &fp);
2385 if (error != 0)
2386 return (error);
2387
2388 if (offset != NULL) {
2389 current_offset = *offset;
2390 } else {
2391 error = (fp->f_ops->fo_flags & DFLAG_SEEKABLE) != 0 ?
2392 fo_seek(fp, 0, SEEK_CUR, td) : ESPIPE;
2393 if (error != 0)
2394 goto drop;
2395 current_offset = td->td_uretoff.tdu_off;
2396 }
2397
2398 bytes_read = 0;
2399
2400 /* Linux cannot have 0 count. */
2401 if (count <= 0 || current_offset < 0) {
2402 error = EINVAL;
2403 goto drop;
2404 }
2405
2406 error = fo_sendfile(fp, out, NULL, NULL, current_offset, count,
2407 &bytes_read, 0, td);
2408 if (error != 0)
2409 goto drop;
2410 current_offset += bytes_read;
2411
2412 if (offset != NULL) {
2413 *offset = current_offset;
2414 } else {
2415 error = fo_seek(fp, current_offset, SEEK_SET, td);
2416 if (error != 0)
2417 goto drop;
2418 }
2419
2420 td->td_retval[0] = (ssize_t)bytes_read;
2421 drop:
2422 fdrop(fp, td);
2423 if (error == ENOTSOCK)
2424 error = EINVAL;
2425 return (error);
2426 }
2427
2428 int
linux_sendfile(struct thread * td,struct linux_sendfile_args * arg)2429 linux_sendfile(struct thread *td, struct linux_sendfile_args *arg)
2430 {
2431 /*
2432 * Differences between FreeBSD and Linux sendfile:
2433 * - Linux doesn't send anything when count is 0 (FreeBSD uses 0 to
2434 * mean send the whole file.) In linux_sendfile given fds are still
2435 * checked for validity when the count is 0.
2436 * - Linux can send to any fd whereas FreeBSD only supports sockets.
2437 * The same restriction follows for linux_sendfile.
2438 * - Linux doesn't have an equivalent for FreeBSD's flags and sf_hdtr.
2439 * - Linux takes an offset pointer and updates it to the read location.
2440 * FreeBSD takes in an offset and a 'bytes read' parameter which is
2441 * only filled if it isn't NULL. We use this parameter to update the
2442 * offset pointer if it exists.
2443 * - Linux sendfile returns bytes read on success while FreeBSD
2444 * returns 0. We use the 'bytes read' parameter to get this value.
2445 */
2446
2447 l_loff_t offset64;
2448 l_long offset;
2449 int ret;
2450 int error;
2451
2452 if (arg->offset != NULL) {
2453 error = copyin(arg->offset, &offset, sizeof(offset));
2454 if (error != 0)
2455 return (error);
2456 offset64 = (l_loff_t)offset;
2457 }
2458
2459 ret = linux_sendfile_common(td, arg->out, arg->in,
2460 arg->offset != NULL ? &offset64 : NULL, arg->count);
2461
2462 if (arg->offset != NULL) {
2463 #if defined(__i386__) || defined(__arm__) || \
2464 (defined(__amd64__) && defined(COMPAT_LINUX32))
2465 if (offset64 > INT32_MAX)
2466 return (EOVERFLOW);
2467 #endif
2468 offset = (l_long)offset64;
2469 error = copyout(&offset, arg->offset, sizeof(offset));
2470 if (error != 0)
2471 return (error);
2472 }
2473
2474 return (ret);
2475 }
2476
2477 #if defined(__i386__) || defined(__arm__) || \
2478 (defined(__amd64__) && defined(COMPAT_LINUX32))
2479
2480 int
linux_sendfile64(struct thread * td,struct linux_sendfile64_args * arg)2481 linux_sendfile64(struct thread *td, struct linux_sendfile64_args *arg)
2482 {
2483 l_loff_t offset;
2484 int ret;
2485 int error;
2486
2487 if (arg->offset != NULL) {
2488 error = copyin(arg->offset, &offset, sizeof(offset));
2489 if (error != 0)
2490 return (error);
2491 }
2492
2493 ret = linux_sendfile_common(td, arg->out, arg->in,
2494 arg->offset != NULL ? &offset : NULL, arg->count);
2495
2496 if (arg->offset != NULL) {
2497 error = copyout(&offset, arg->offset, sizeof(offset));
2498 if (error != 0)
2499 return (error);
2500 }
2501
2502 return (ret);
2503 }
2504
2505 /* Argument list sizes for linux_socketcall */
2506 static const unsigned char lxs_args_cnt[] = {
2507 0 /* unused*/, 3 /* socket */,
2508 3 /* bind */, 3 /* connect */,
2509 2 /* listen */, 3 /* accept */,
2510 3 /* getsockname */, 3 /* getpeername */,
2511 4 /* socketpair */, 4 /* send */,
2512 4 /* recv */, 6 /* sendto */,
2513 6 /* recvfrom */, 2 /* shutdown */,
2514 5 /* setsockopt */, 5 /* getsockopt */,
2515 3 /* sendmsg */, 3 /* recvmsg */,
2516 4 /* accept4 */, 5 /* recvmmsg */,
2517 4 /* sendmmsg */, 4 /* sendfile */
2518 };
2519 #define LINUX_ARGS_CNT (nitems(lxs_args_cnt) - 1)
2520 #define LINUX_ARG_SIZE(x) (lxs_args_cnt[x] * sizeof(l_ulong))
2521
2522 int
linux_socketcall(struct thread * td,struct linux_socketcall_args * args)2523 linux_socketcall(struct thread *td, struct linux_socketcall_args *args)
2524 {
2525 l_ulong a[6];
2526 #if defined(__amd64__) && defined(COMPAT_LINUX32)
2527 register_t l_args[6];
2528 #endif
2529 void *arg;
2530 int error;
2531
2532 if (args->what < LINUX_SOCKET || args->what > LINUX_ARGS_CNT)
2533 return (EINVAL);
2534 error = copyin(PTRIN(args->args), a, LINUX_ARG_SIZE(args->what));
2535 if (error != 0)
2536 return (error);
2537
2538 #if defined(__amd64__) && defined(COMPAT_LINUX32)
2539 for (int i = 0; i < lxs_args_cnt[args->what]; ++i)
2540 l_args[i] = a[i];
2541 arg = l_args;
2542 #else
2543 arg = a;
2544 #endif
2545 switch (args->what) {
2546 case LINUX_SOCKET:
2547 return (linux_socket(td, arg));
2548 case LINUX_BIND:
2549 return (linux_bind(td, arg));
2550 case LINUX_CONNECT:
2551 return (linux_connect(td, arg));
2552 case LINUX_LISTEN:
2553 return (linux_listen(td, arg));
2554 case LINUX_ACCEPT:
2555 return (linux_accept(td, arg));
2556 case LINUX_GETSOCKNAME:
2557 return (linux_getsockname(td, arg));
2558 case LINUX_GETPEERNAME:
2559 return (linux_getpeername(td, arg));
2560 case LINUX_SOCKETPAIR:
2561 return (linux_socketpair(td, arg));
2562 case LINUX_SEND:
2563 return (linux_send(td, arg));
2564 case LINUX_RECV:
2565 return (linux_recv(td, arg));
2566 case LINUX_SENDTO:
2567 return (linux_sendto(td, arg));
2568 case LINUX_RECVFROM:
2569 return (linux_recvfrom(td, arg));
2570 case LINUX_SHUTDOWN:
2571 return (linux_shutdown(td, arg));
2572 case LINUX_SETSOCKOPT:
2573 return (linux_setsockopt(td, arg));
2574 case LINUX_GETSOCKOPT:
2575 return (linux_getsockopt(td, arg));
2576 case LINUX_SENDMSG:
2577 return (linux_sendmsg(td, arg));
2578 case LINUX_RECVMSG:
2579 return (linux_recvmsg(td, arg));
2580 case LINUX_ACCEPT4:
2581 return (linux_accept4(td, arg));
2582 case LINUX_RECVMMSG:
2583 return (linux_recvmmsg(td, arg));
2584 case LINUX_SENDMMSG:
2585 return (linux_sendmmsg(td, arg));
2586 case LINUX_SENDFILE:
2587 return (linux_sendfile(td, arg));
2588 }
2589
2590 linux_msg(td, "socket type %d not implemented", args->what);
2591 return (ENOSYS);
2592 }
2593 #endif /* __i386__ || __arm__ || (__amd64__ && COMPAT_LINUX32) */
2594