Line data Source code
1 : // SPDX-License-Identifier: GPL-2.0
2 : /*
3 : * INET An implementation of the TCP/IP protocol suite for the LINUX
4 : * operating system. INET is implemented using the BSD Socket
5 : * interface as the means of communication with the user level.
6 : *
7 : * The IP to API glue.
8 : *
9 : * Authors: see ip.c
10 : *
11 : * Fixes:
12 : * Many : Split from ip.c , see ip.c for history.
13 : * Martin Mares : TOS setting fixed.
14 : * Alan Cox : Fixed a couple of oopses in Martin's
15 : * TOS tweaks.
16 : * Mike McLagan : Routing by source
17 : */
18 :
19 : #include <linux/module.h>
20 : #include <linux/types.h>
21 : #include <linux/mm.h>
22 : #include <linux/skbuff.h>
23 : #include <linux/ip.h>
24 : #include <linux/icmp.h>
25 : #include <linux/inetdevice.h>
26 : #include <linux/netdevice.h>
27 : #include <linux/slab.h>
28 : #include <net/sock.h>
29 : #include <net/ip.h>
30 : #include <net/icmp.h>
31 : #include <net/tcp_states.h>
32 : #include <linux/udp.h>
33 : #include <linux/igmp.h>
34 : #include <linux/netfilter.h>
35 : #include <linux/route.h>
36 : #include <linux/mroute.h>
37 : #include <net/inet_ecn.h>
38 : #include <net/route.h>
39 : #include <net/xfrm.h>
40 : #include <net/compat.h>
41 : #include <net/checksum.h>
42 : #if IS_ENABLED(CONFIG_IPV6)
43 : #include <net/transp_v6.h>
44 : #endif
45 : #include <net/ip_fib.h>
46 :
47 : #include <linux/errqueue.h>
48 : #include <linux/uaccess.h>
49 :
50 : #include <linux/bpfilter.h>
51 :
52 : /*
53 : * SOL_IP control messages.
54 : */
55 :
56 0 : static void ip_cmsg_recv_pktinfo(struct msghdr *msg, struct sk_buff *skb)
57 : {
58 0 : struct in_pktinfo info = *PKTINFO_SKB_CB(skb);
59 :
60 0 : info.ipi_addr.s_addr = ip_hdr(skb)->daddr;
61 :
62 0 : put_cmsg(msg, SOL_IP, IP_PKTINFO, sizeof(info), &info);
63 0 : }
64 :
65 0 : static void ip_cmsg_recv_ttl(struct msghdr *msg, struct sk_buff *skb)
66 : {
67 0 : int ttl = ip_hdr(skb)->ttl;
68 0 : put_cmsg(msg, SOL_IP, IP_TTL, sizeof(int), &ttl);
69 0 : }
70 :
71 0 : static void ip_cmsg_recv_tos(struct msghdr *msg, struct sk_buff *skb)
72 : {
73 0 : put_cmsg(msg, SOL_IP, IP_TOS, 1, &ip_hdr(skb)->tos);
74 0 : }
75 :
76 0 : static void ip_cmsg_recv_opts(struct msghdr *msg, struct sk_buff *skb)
77 : {
78 0 : if (IPCB(skb)->opt.optlen == 0)
79 : return;
80 :
81 0 : put_cmsg(msg, SOL_IP, IP_RECVOPTS, IPCB(skb)->opt.optlen,
82 0 : ip_hdr(skb) + 1);
83 : }
84 :
85 :
86 0 : static void ip_cmsg_recv_retopts(struct net *net, struct msghdr *msg,
87 : struct sk_buff *skb)
88 : {
89 0 : unsigned char optbuf[sizeof(struct ip_options) + 40];
90 0 : struct ip_options *opt = (struct ip_options *)optbuf;
91 :
92 0 : if (IPCB(skb)->opt.optlen == 0)
93 0 : return;
94 :
95 0 : if (ip_options_echo(net, opt, skb)) {
96 0 : msg->msg_flags |= MSG_CTRUNC;
97 0 : return;
98 : }
99 0 : ip_options_undo(opt);
100 :
101 0 : put_cmsg(msg, SOL_IP, IP_RETOPTS, opt->optlen, opt->__data);
102 : }
103 :
104 0 : static void ip_cmsg_recv_fragsize(struct msghdr *msg, struct sk_buff *skb)
105 : {
106 0 : int val;
107 :
108 0 : if (IPCB(skb)->frag_max_size == 0)
109 0 : return;
110 :
111 0 : val = IPCB(skb)->frag_max_size;
112 0 : put_cmsg(msg, SOL_IP, IP_RECVFRAGSIZE, sizeof(val), &val);
113 : }
114 :
115 0 : static void ip_cmsg_recv_checksum(struct msghdr *msg, struct sk_buff *skb,
116 : int tlen, int offset)
117 : {
118 0 : __wsum csum = skb->csum;
119 :
120 0 : if (skb->ip_summed != CHECKSUM_COMPLETE)
121 0 : return;
122 :
123 0 : if (offset != 0) {
124 0 : int tend_off = skb_transport_offset(skb) + tlen;
125 0 : csum = csum_sub(csum, skb_checksum(skb, tend_off, offset, 0));
126 : }
127 :
128 0 : put_cmsg(msg, SOL_IP, IP_CHECKSUM, sizeof(__wsum), &csum);
129 : }
130 :
131 0 : static void ip_cmsg_recv_security(struct msghdr *msg, struct sk_buff *skb)
132 : {
133 0 : char *secdata;
134 0 : u32 seclen, secid;
135 0 : int err;
136 :
137 0 : err = security_socket_getpeersec_dgram(NULL, skb, &secid);
138 0 : if (err)
139 0 : return;
140 :
141 : err = security_secid_to_secctx(secid, &secdata, &seclen);
142 : if (err)
143 : return;
144 :
145 : put_cmsg(msg, SOL_IP, SCM_SECURITY, seclen, secdata);
146 : security_release_secctx(secdata, seclen);
147 : }
148 :
149 0 : static void ip_cmsg_recv_dstaddr(struct msghdr *msg, struct sk_buff *skb)
150 : {
151 0 : __be16 _ports[2], *ports;
152 0 : struct sockaddr_in sin;
153 :
154 : /* All current transport protocols have the port numbers in the
155 : * first four bytes of the transport header and this function is
156 : * written with this assumption in mind.
157 : */
158 0 : ports = skb_header_pointer(skb, skb_transport_offset(skb),
159 : sizeof(_ports), &_ports);
160 0 : if (!ports)
161 0 : return;
162 :
163 0 : sin.sin_family = AF_INET;
164 0 : sin.sin_addr.s_addr = ip_hdr(skb)->daddr;
165 0 : sin.sin_port = ports[1];
166 0 : memset(sin.sin_zero, 0, sizeof(sin.sin_zero));
167 :
168 0 : put_cmsg(msg, SOL_IP, IP_ORIGDSTADDR, sizeof(sin), &sin);
169 : }
170 :
171 0 : void ip_cmsg_recv_offset(struct msghdr *msg, struct sock *sk,
172 : struct sk_buff *skb, int tlen, int offset)
173 : {
174 0 : struct inet_sock *inet = inet_sk(sk);
175 0 : unsigned int flags = inet->cmsg_flags;
176 :
177 : /* Ordered by supposed usage frequency */
178 0 : if (flags & IP_CMSG_PKTINFO) {
179 0 : ip_cmsg_recv_pktinfo(msg, skb);
180 :
181 0 : flags &= ~IP_CMSG_PKTINFO;
182 0 : if (!flags)
183 : return;
184 : }
185 :
186 0 : if (flags & IP_CMSG_TTL) {
187 0 : ip_cmsg_recv_ttl(msg, skb);
188 :
189 0 : flags &= ~IP_CMSG_TTL;
190 0 : if (!flags)
191 : return;
192 : }
193 :
194 0 : if (flags & IP_CMSG_TOS) {
195 0 : ip_cmsg_recv_tos(msg, skb);
196 :
197 0 : flags &= ~IP_CMSG_TOS;
198 0 : if (!flags)
199 : return;
200 : }
201 :
202 0 : if (flags & IP_CMSG_RECVOPTS) {
203 0 : ip_cmsg_recv_opts(msg, skb);
204 :
205 0 : flags &= ~IP_CMSG_RECVOPTS;
206 0 : if (!flags)
207 : return;
208 : }
209 :
210 0 : if (flags & IP_CMSG_RETOPTS) {
211 0 : ip_cmsg_recv_retopts(sock_net(sk), msg, skb);
212 :
213 0 : flags &= ~IP_CMSG_RETOPTS;
214 0 : if (!flags)
215 : return;
216 : }
217 :
218 0 : if (flags & IP_CMSG_PASSSEC) {
219 0 : ip_cmsg_recv_security(msg, skb);
220 :
221 0 : flags &= ~IP_CMSG_PASSSEC;
222 0 : if (!flags)
223 : return;
224 : }
225 :
226 0 : if (flags & IP_CMSG_ORIGDSTADDR) {
227 0 : ip_cmsg_recv_dstaddr(msg, skb);
228 :
229 0 : flags &= ~IP_CMSG_ORIGDSTADDR;
230 0 : if (!flags)
231 : return;
232 : }
233 :
234 0 : if (flags & IP_CMSG_CHECKSUM)
235 0 : ip_cmsg_recv_checksum(msg, skb, tlen, offset);
236 :
237 0 : if (flags & IP_CMSG_RECVFRAGSIZE)
238 0 : ip_cmsg_recv_fragsize(msg, skb);
239 : }
240 : EXPORT_SYMBOL(ip_cmsg_recv_offset);
241 :
242 0 : int ip_cmsg_send(struct sock *sk, struct msghdr *msg, struct ipcm_cookie *ipc,
243 : bool allow_ipv6)
244 : {
245 0 : int err, val;
246 0 : struct cmsghdr *cmsg;
247 0 : struct net *net = sock_net(sk);
248 :
249 0 : for_each_cmsghdr(cmsg, msg) {
250 0 : if (!CMSG_OK(msg, cmsg))
251 : return -EINVAL;
252 : #if IS_ENABLED(CONFIG_IPV6)
253 : if (allow_ipv6 &&
254 : cmsg->cmsg_level == SOL_IPV6 &&
255 : cmsg->cmsg_type == IPV6_PKTINFO) {
256 : struct in6_pktinfo *src_info;
257 :
258 : if (cmsg->cmsg_len < CMSG_LEN(sizeof(*src_info)))
259 : return -EINVAL;
260 : src_info = (struct in6_pktinfo *)CMSG_DATA(cmsg);
261 : if (!ipv6_addr_v4mapped(&src_info->ipi6_addr))
262 : return -EINVAL;
263 : if (src_info->ipi6_ifindex)
264 : ipc->oif = src_info->ipi6_ifindex;
265 : ipc->addr = src_info->ipi6_addr.s6_addr32[3];
266 : continue;
267 : }
268 : #endif
269 0 : if (cmsg->cmsg_level == SOL_SOCKET) {
270 0 : err = __sock_cmsg_send(sk, msg, cmsg, &ipc->sockc);
271 0 : if (err)
272 0 : return err;
273 0 : continue;
274 : }
275 :
276 0 : if (cmsg->cmsg_level != SOL_IP)
277 0 : continue;
278 0 : switch (cmsg->cmsg_type) {
279 0 : case IP_RETOPTS:
280 0 : err = cmsg->cmsg_len - sizeof(struct cmsghdr);
281 :
282 : /* Our caller is responsible for freeing ipc->opt */
283 0 : err = ip_options_get(net, &ipc->opt,
284 : KERNEL_SOCKPTR(CMSG_DATA(cmsg)),
285 : err < 40 ? err : 40);
286 0 : if (err)
287 0 : return err;
288 : break;
289 0 : case IP_PKTINFO:
290 : {
291 0 : struct in_pktinfo *info;
292 0 : if (cmsg->cmsg_len != CMSG_LEN(sizeof(struct in_pktinfo)))
293 : return -EINVAL;
294 0 : info = (struct in_pktinfo *)CMSG_DATA(cmsg);
295 0 : if (info->ipi_ifindex)
296 0 : ipc->oif = info->ipi_ifindex;
297 0 : ipc->addr = info->ipi_spec_dst.s_addr;
298 0 : break;
299 : }
300 0 : case IP_TTL:
301 0 : if (cmsg->cmsg_len != CMSG_LEN(sizeof(int)))
302 : return -EINVAL;
303 0 : val = *(int *)CMSG_DATA(cmsg);
304 0 : if (val < 1 || val > 255)
305 : return -EINVAL;
306 0 : ipc->ttl = val;
307 0 : break;
308 0 : case IP_TOS:
309 0 : if (cmsg->cmsg_len == CMSG_LEN(sizeof(int)))
310 0 : val = *(int *)CMSG_DATA(cmsg);
311 0 : else if (cmsg->cmsg_len == CMSG_LEN(sizeof(u8)))
312 0 : val = *(u8 *)CMSG_DATA(cmsg);
313 : else
314 : return -EINVAL;
315 0 : if (val < 0 || val > 255)
316 : return -EINVAL;
317 0 : ipc->tos = val;
318 0 : ipc->priority = rt_tos2priority(ipc->tos);
319 0 : break;
320 :
321 : default:
322 : return -EINVAL;
323 : }
324 : }
325 : return 0;
326 : }
327 :
328 0 : static void ip_ra_destroy_rcu(struct rcu_head *head)
329 : {
330 0 : struct ip_ra_chain *ra = container_of(head, struct ip_ra_chain, rcu);
331 :
332 0 : sock_put(ra->saved_sk);
333 0 : kfree(ra);
334 0 : }
335 :
336 0 : int ip_ra_control(struct sock *sk, unsigned char on,
337 : void (*destructor)(struct sock *))
338 : {
339 0 : struct ip_ra_chain *ra, *new_ra;
340 0 : struct ip_ra_chain __rcu **rap;
341 0 : struct net *net = sock_net(sk);
342 :
343 0 : if (sk->sk_type != SOCK_RAW || inet_sk(sk)->inet_num == IPPROTO_RAW)
344 : return -EINVAL;
345 :
346 0 : new_ra = on ? kmalloc(sizeof(*new_ra), GFP_KERNEL) : NULL;
347 0 : if (on && !new_ra)
348 : return -ENOMEM;
349 :
350 0 : mutex_lock(&net->ipv4.ra_mutex);
351 0 : for (rap = &net->ipv4.ra_chain;
352 0 : (ra = rcu_dereference_protected(*rap,
353 : lockdep_is_held(&net->ipv4.ra_mutex))) != NULL;
354 0 : rap = &ra->next) {
355 0 : if (ra->sk == sk) {
356 0 : if (on) {
357 0 : mutex_unlock(&net->ipv4.ra_mutex);
358 0 : kfree(new_ra);
359 0 : return -EADDRINUSE;
360 : }
361 : /* dont let ip_call_ra_chain() use sk again */
362 0 : ra->sk = NULL;
363 0 : RCU_INIT_POINTER(*rap, ra->next);
364 0 : mutex_unlock(&net->ipv4.ra_mutex);
365 :
366 0 : if (ra->destructor)
367 0 : ra->destructor(sk);
368 : /*
369 : * Delay sock_put(sk) and kfree(ra) after one rcu grace
370 : * period. This guarantee ip_call_ra_chain() dont need
371 : * to mess with socket refcounts.
372 : */
373 0 : ra->saved_sk = sk;
374 0 : call_rcu(&ra->rcu, ip_ra_destroy_rcu);
375 0 : return 0;
376 : }
377 : }
378 0 : if (!new_ra) {
379 0 : mutex_unlock(&net->ipv4.ra_mutex);
380 0 : return -ENOBUFS;
381 : }
382 0 : new_ra->sk = sk;
383 0 : new_ra->destructor = destructor;
384 :
385 0 : RCU_INIT_POINTER(new_ra->next, ra);
386 0 : rcu_assign_pointer(*rap, new_ra);
387 0 : sock_hold(sk);
388 0 : mutex_unlock(&net->ipv4.ra_mutex);
389 :
390 0 : return 0;
391 : }
392 :
393 0 : static void ipv4_icmp_error_rfc4884(const struct sk_buff *skb,
394 : struct sock_ee_data_rfc4884 *out)
395 : {
396 0 : switch (icmp_hdr(skb)->type) {
397 : case ICMP_DEST_UNREACH:
398 : case ICMP_TIME_EXCEEDED:
399 : case ICMP_PARAMETERPROB:
400 0 : ip_icmp_error_rfc4884(skb, out, sizeof(struct icmphdr),
401 0 : icmp_hdr(skb)->un.reserved[1] * 4);
402 : }
403 0 : }
404 :
405 0 : void ip_icmp_error(struct sock *sk, struct sk_buff *skb, int err,
406 : __be16 port, u32 info, u8 *payload)
407 : {
408 0 : struct sock_exterr_skb *serr;
409 :
410 0 : skb = skb_clone(skb, GFP_ATOMIC);
411 0 : if (!skb)
412 : return;
413 :
414 0 : serr = SKB_EXT_ERR(skb);
415 0 : serr->ee.ee_errno = err;
416 0 : serr->ee.ee_origin = SO_EE_ORIGIN_ICMP;
417 0 : serr->ee.ee_type = icmp_hdr(skb)->type;
418 0 : serr->ee.ee_code = icmp_hdr(skb)->code;
419 0 : serr->ee.ee_pad = 0;
420 0 : serr->ee.ee_info = info;
421 0 : serr->ee.ee_data = 0;
422 0 : serr->addr_offset = (u8 *)&(((struct iphdr *)(icmp_hdr(skb) + 1))->daddr) -
423 0 : skb_network_header(skb);
424 0 : serr->port = port;
425 :
426 0 : if (skb_pull(skb, payload - skb->data)) {
427 0 : if (inet_sk(sk)->recverr_rfc4884)
428 0 : ipv4_icmp_error_rfc4884(skb, &serr->ee.ee_rfc4884);
429 :
430 0 : skb_reset_transport_header(skb);
431 0 : if (sock_queue_err_skb(sk, skb) == 0)
432 : return;
433 : }
434 0 : kfree_skb(skb);
435 : }
436 :
437 0 : void ip_local_error(struct sock *sk, int err, __be32 daddr, __be16 port, u32 info)
438 : {
439 0 : struct inet_sock *inet = inet_sk(sk);
440 0 : struct sock_exterr_skb *serr;
441 0 : struct iphdr *iph;
442 0 : struct sk_buff *skb;
443 :
444 0 : if (!inet->recverr)
445 : return;
446 :
447 0 : skb = alloc_skb(sizeof(struct iphdr), GFP_ATOMIC);
448 0 : if (!skb)
449 : return;
450 :
451 0 : skb_put(skb, sizeof(struct iphdr));
452 0 : skb_reset_network_header(skb);
453 0 : iph = ip_hdr(skb);
454 0 : iph->daddr = daddr;
455 :
456 0 : serr = SKB_EXT_ERR(skb);
457 0 : serr->ee.ee_errno = err;
458 0 : serr->ee.ee_origin = SO_EE_ORIGIN_LOCAL;
459 0 : serr->ee.ee_type = 0;
460 0 : serr->ee.ee_code = 0;
461 0 : serr->ee.ee_pad = 0;
462 0 : serr->ee.ee_info = info;
463 0 : serr->ee.ee_data = 0;
464 0 : serr->addr_offset = (u8 *)&iph->daddr - skb_network_header(skb);
465 0 : serr->port = port;
466 :
467 0 : __skb_pull(skb, skb_tail_pointer(skb) - skb->data);
468 0 : skb_reset_transport_header(skb);
469 :
470 0 : if (sock_queue_err_skb(sk, skb))
471 0 : kfree_skb(skb);
472 : }
473 :
474 : /* For some errors we have valid addr_offset even with zero payload and
475 : * zero port. Also, addr_offset should be supported if port is set.
476 : */
477 0 : static inline bool ipv4_datagram_support_addr(struct sock_exterr_skb *serr)
478 : {
479 0 : return serr->ee.ee_origin == SO_EE_ORIGIN_ICMP ||
480 0 : serr->ee.ee_origin == SO_EE_ORIGIN_LOCAL || serr->port;
481 : }
482 :
483 : /* IPv4 supports cmsg on all imcp errors and some timestamps
484 : *
485 : * Timestamp code paths do not initialize the fields expected by cmsg:
486 : * the PKTINFO fields in skb->cb[]. Fill those in here.
487 : */
488 0 : static bool ipv4_datagram_support_cmsg(const struct sock *sk,
489 : struct sk_buff *skb,
490 : int ee_origin)
491 : {
492 0 : struct in_pktinfo *info;
493 :
494 0 : if (ee_origin == SO_EE_ORIGIN_ICMP)
495 : return true;
496 :
497 0 : if (ee_origin == SO_EE_ORIGIN_LOCAL)
498 : return false;
499 :
500 : /* Support IP_PKTINFO on tstamp packets if requested, to correlate
501 : * timestamp with egress dev. Not possible for packets without iif
502 : * or without payload (SOF_TIMESTAMPING_OPT_TSONLY).
503 : */
504 0 : info = PKTINFO_SKB_CB(skb);
505 0 : if (!(sk->sk_tsflags & SOF_TIMESTAMPING_OPT_CMSG) ||
506 0 : !info->ipi_ifindex)
507 : return false;
508 :
509 0 : info->ipi_spec_dst.s_addr = ip_hdr(skb)->saddr;
510 0 : return true;
511 : }
512 :
513 : /*
514 : * Handle MSG_ERRQUEUE
515 : */
516 0 : int ip_recv_error(struct sock *sk, struct msghdr *msg, int len, int *addr_len)
517 : {
518 0 : struct sock_exterr_skb *serr;
519 0 : struct sk_buff *skb;
520 0 : DECLARE_SOCKADDR(struct sockaddr_in *, sin, msg->msg_name);
521 0 : struct {
522 : struct sock_extended_err ee;
523 : struct sockaddr_in offender;
524 : } errhdr;
525 0 : int err;
526 0 : int copied;
527 :
528 0 : err = -EAGAIN;
529 0 : skb = sock_dequeue_err_skb(sk);
530 0 : if (!skb)
531 0 : goto out;
532 :
533 0 : copied = skb->len;
534 0 : if (copied > len) {
535 0 : msg->msg_flags |= MSG_TRUNC;
536 0 : copied = len;
537 : }
538 0 : err = skb_copy_datagram_msg(skb, 0, msg, copied);
539 0 : if (unlikely(err)) {
540 0 : kfree_skb(skb);
541 0 : return err;
542 : }
543 0 : sock_recv_timestamp(msg, sk, skb);
544 :
545 0 : serr = SKB_EXT_ERR(skb);
546 :
547 0 : if (sin && ipv4_datagram_support_addr(serr)) {
548 0 : sin->sin_family = AF_INET;
549 0 : sin->sin_addr.s_addr = *(__be32 *)(skb_network_header(skb) +
550 0 : serr->addr_offset);
551 0 : sin->sin_port = serr->port;
552 0 : memset(&sin->sin_zero, 0, sizeof(sin->sin_zero));
553 0 : *addr_len = sizeof(*sin);
554 : }
555 :
556 0 : memcpy(&errhdr.ee, &serr->ee, sizeof(struct sock_extended_err));
557 0 : sin = &errhdr.offender;
558 0 : memset(sin, 0, sizeof(*sin));
559 :
560 0 : if (ipv4_datagram_support_cmsg(sk, skb, serr->ee.ee_origin)) {
561 0 : sin->sin_family = AF_INET;
562 0 : sin->sin_addr.s_addr = ip_hdr(skb)->saddr;
563 0 : if (inet_sk(sk)->cmsg_flags)
564 0 : ip_cmsg_recv(msg, skb);
565 : }
566 :
567 0 : put_cmsg(msg, SOL_IP, IP_RECVERR, sizeof(errhdr), &errhdr);
568 :
569 : /* Now we could try to dump offended packet options */
570 :
571 0 : msg->msg_flags |= MSG_ERRQUEUE;
572 0 : err = copied;
573 :
574 0 : consume_skb(skb);
575 : out:
576 : return err;
577 : }
578 :
579 4 : static void __ip_sock_set_tos(struct sock *sk, int val)
580 : {
581 4 : if (sk->sk_type == SOCK_STREAM) {
582 4 : val &= ~INET_ECN_MASK;
583 4 : val |= inet_sk(sk)->tos & INET_ECN_MASK;
584 : }
585 4 : if (inet_sk(sk)->tos != val) {
586 4 : inet_sk(sk)->tos = val;
587 4 : sk->sk_priority = rt_tos2priority(val);
588 4 : sk_dst_reset(sk);
589 : }
590 4 : }
591 :
592 0 : void ip_sock_set_tos(struct sock *sk, int val)
593 : {
594 0 : lock_sock(sk);
595 0 : __ip_sock_set_tos(sk, val);
596 0 : release_sock(sk);
597 0 : }
598 : EXPORT_SYMBOL(ip_sock_set_tos);
599 :
600 0 : void ip_sock_set_freebind(struct sock *sk)
601 : {
602 0 : lock_sock(sk);
603 0 : inet_sk(sk)->freebind = true;
604 0 : release_sock(sk);
605 0 : }
606 : EXPORT_SYMBOL(ip_sock_set_freebind);
607 :
608 0 : void ip_sock_set_recverr(struct sock *sk)
609 : {
610 0 : lock_sock(sk);
611 0 : inet_sk(sk)->recverr = true;
612 0 : release_sock(sk);
613 0 : }
614 : EXPORT_SYMBOL(ip_sock_set_recverr);
615 :
616 0 : int ip_sock_set_mtu_discover(struct sock *sk, int val)
617 : {
618 0 : if (val < IP_PMTUDISC_DONT || val > IP_PMTUDISC_OMIT)
619 : return -EINVAL;
620 0 : lock_sock(sk);
621 0 : inet_sk(sk)->pmtudisc = val;
622 0 : release_sock(sk);
623 0 : return 0;
624 : }
625 : EXPORT_SYMBOL(ip_sock_set_mtu_discover);
626 :
627 0 : void ip_sock_set_pktinfo(struct sock *sk)
628 : {
629 0 : lock_sock(sk);
630 0 : inet_sk(sk)->cmsg_flags |= IP_CMSG_PKTINFO;
631 0 : release_sock(sk);
632 0 : }
633 : EXPORT_SYMBOL(ip_sock_set_pktinfo);
634 :
635 : /*
636 : * Socket option code for IP. This is the end of the line after any
637 : * TCP,UDP etc options on an IP socket.
638 : */
639 5 : static bool setsockopt_needs_rtnl(int optname)
640 : {
641 5 : switch (optname) {
642 : case IP_ADD_MEMBERSHIP:
643 : case IP_ADD_SOURCE_MEMBERSHIP:
644 : case IP_BLOCK_SOURCE:
645 : case IP_DROP_MEMBERSHIP:
646 : case IP_DROP_SOURCE_MEMBERSHIP:
647 : case IP_MSFILTER:
648 : case IP_UNBLOCK_SOURCE:
649 : case MCAST_BLOCK_SOURCE:
650 : case MCAST_MSFILTER:
651 : case MCAST_JOIN_GROUP:
652 : case MCAST_JOIN_SOURCE_GROUP:
653 : case MCAST_LEAVE_GROUP:
654 : case MCAST_LEAVE_SOURCE_GROUP:
655 : case MCAST_UNBLOCK_SOURCE:
656 : return true;
657 : }
658 5 : return false;
659 : }
660 :
661 0 : static int set_mcast_msfilter(struct sock *sk, int ifindex,
662 : int numsrc, int fmode,
663 : struct sockaddr_storage *group,
664 : struct sockaddr_storage *list)
665 : {
666 0 : int msize = IP_MSFILTER_SIZE(numsrc);
667 0 : struct ip_msfilter *msf;
668 0 : struct sockaddr_in *psin;
669 0 : int err, i;
670 :
671 0 : msf = kmalloc(msize, GFP_KERNEL);
672 0 : if (!msf)
673 : return -ENOBUFS;
674 :
675 0 : psin = (struct sockaddr_in *)group;
676 0 : if (psin->sin_family != AF_INET)
677 0 : goto Eaddrnotavail;
678 0 : msf->imsf_multiaddr = psin->sin_addr.s_addr;
679 0 : msf->imsf_interface = 0;
680 0 : msf->imsf_fmode = fmode;
681 0 : msf->imsf_numsrc = numsrc;
682 0 : for (i = 0; i < numsrc; ++i) {
683 0 : psin = (struct sockaddr_in *)&list[i];
684 :
685 0 : if (psin->sin_family != AF_INET)
686 0 : goto Eaddrnotavail;
687 0 : msf->imsf_slist[i] = psin->sin_addr.s_addr;
688 : }
689 0 : err = ip_mc_msfilter(sk, msf, ifindex);
690 0 : kfree(msf);
691 0 : return err;
692 :
693 0 : Eaddrnotavail:
694 0 : kfree(msf);
695 0 : return -EADDRNOTAVAIL;
696 : }
697 :
698 0 : static int copy_group_source_from_sockptr(struct group_source_req *greqs,
699 : sockptr_t optval, int optlen)
700 : {
701 0 : if (in_compat_syscall()) {
702 0 : struct compat_group_source_req gr32;
703 :
704 0 : if (optlen != sizeof(gr32))
705 0 : return -EINVAL;
706 0 : if (copy_from_sockptr(&gr32, optval, sizeof(gr32)))
707 : return -EFAULT;
708 0 : greqs->gsr_interface = gr32.gsr_interface;
709 0 : greqs->gsr_group = gr32.gsr_group;
710 0 : greqs->gsr_source = gr32.gsr_source;
711 : } else {
712 0 : if (optlen != sizeof(*greqs))
713 : return -EINVAL;
714 0 : if (copy_from_sockptr(greqs, optval, sizeof(*greqs)))
715 0 : return -EFAULT;
716 : }
717 :
718 : return 0;
719 : }
720 :
721 0 : static int do_mcast_group_source(struct sock *sk, int optname,
722 : sockptr_t optval, int optlen)
723 : {
724 0 : struct group_source_req greqs;
725 0 : struct ip_mreq_source mreqs;
726 0 : struct sockaddr_in *psin;
727 0 : int omode, add, err;
728 :
729 0 : err = copy_group_source_from_sockptr(&greqs, optval, optlen);
730 0 : if (err)
731 : return err;
732 :
733 0 : if (greqs.gsr_group.ss_family != AF_INET ||
734 0 : greqs.gsr_source.ss_family != AF_INET)
735 : return -EADDRNOTAVAIL;
736 :
737 0 : psin = (struct sockaddr_in *)&greqs.gsr_group;
738 0 : mreqs.imr_multiaddr = psin->sin_addr.s_addr;
739 0 : psin = (struct sockaddr_in *)&greqs.gsr_source;
740 0 : mreqs.imr_sourceaddr = psin->sin_addr.s_addr;
741 0 : mreqs.imr_interface = 0; /* use index for mc_source */
742 :
743 0 : if (optname == MCAST_BLOCK_SOURCE) {
744 : omode = MCAST_EXCLUDE;
745 : add = 1;
746 0 : } else if (optname == MCAST_UNBLOCK_SOURCE) {
747 : omode = MCAST_EXCLUDE;
748 : add = 0;
749 0 : } else if (optname == MCAST_JOIN_SOURCE_GROUP) {
750 0 : struct ip_mreqn mreq;
751 :
752 0 : psin = (struct sockaddr_in *)&greqs.gsr_group;
753 0 : mreq.imr_multiaddr = psin->sin_addr;
754 0 : mreq.imr_address.s_addr = 0;
755 0 : mreq.imr_ifindex = greqs.gsr_interface;
756 0 : err = ip_mc_join_group_ssm(sk, &mreq, MCAST_INCLUDE);
757 0 : if (err && err != -EADDRINUSE)
758 0 : return err;
759 0 : greqs.gsr_interface = mreq.imr_ifindex;
760 0 : omode = MCAST_INCLUDE;
761 0 : add = 1;
762 : } else /* MCAST_LEAVE_SOURCE_GROUP */ {
763 : omode = MCAST_INCLUDE;
764 : add = 0;
765 : }
766 0 : return ip_mc_source(add, omode, sk, &mreqs, greqs.gsr_interface);
767 : }
768 :
769 0 : static int ip_set_mcast_msfilter(struct sock *sk, sockptr_t optval, int optlen)
770 : {
771 0 : struct group_filter *gsf = NULL;
772 0 : int err;
773 :
774 0 : if (optlen < GROUP_FILTER_SIZE(0))
775 : return -EINVAL;
776 0 : if (optlen > sysctl_optmem_max)
777 : return -ENOBUFS;
778 :
779 0 : gsf = memdup_sockptr(optval, optlen);
780 0 : if (IS_ERR(gsf))
781 0 : return PTR_ERR(gsf);
782 :
783 : /* numsrc >= (4G-140)/128 overflow in 32 bits */
784 0 : err = -ENOBUFS;
785 0 : if (gsf->gf_numsrc >= 0x1ffffff ||
786 0 : gsf->gf_numsrc > sock_net(sk)->ipv4.sysctl_igmp_max_msf)
787 0 : goto out_free_gsf;
788 :
789 0 : err = -EINVAL;
790 0 : if (GROUP_FILTER_SIZE(gsf->gf_numsrc) > optlen)
791 0 : goto out_free_gsf;
792 :
793 0 : err = set_mcast_msfilter(sk, gsf->gf_interface, gsf->gf_numsrc,
794 0 : gsf->gf_fmode, &gsf->gf_group, gsf->gf_slist);
795 0 : out_free_gsf:
796 0 : kfree(gsf);
797 0 : return err;
798 : }
799 :
800 0 : static int compat_ip_set_mcast_msfilter(struct sock *sk, sockptr_t optval,
801 : int optlen)
802 : {
803 0 : const int size0 = offsetof(struct compat_group_filter, gf_slist);
804 0 : struct compat_group_filter *gf32;
805 0 : unsigned int n;
806 0 : void *p;
807 0 : int err;
808 :
809 0 : if (optlen < size0)
810 : return -EINVAL;
811 0 : if (optlen > sysctl_optmem_max - 4)
812 : return -ENOBUFS;
813 :
814 0 : p = kmalloc(optlen + 4, GFP_KERNEL);
815 0 : if (!p)
816 : return -ENOMEM;
817 0 : gf32 = p + 4; /* we want ->gf_group and ->gf_slist aligned */
818 :
819 0 : err = -EFAULT;
820 0 : if (copy_from_sockptr(gf32, optval, optlen))
821 0 : goto out_free_gsf;
822 :
823 : /* numsrc >= (4G-140)/128 overflow in 32 bits */
824 0 : n = gf32->gf_numsrc;
825 0 : err = -ENOBUFS;
826 0 : if (n >= 0x1ffffff)
827 0 : goto out_free_gsf;
828 :
829 0 : err = -EINVAL;
830 0 : if (offsetof(struct compat_group_filter, gf_slist[n]) > optlen)
831 0 : goto out_free_gsf;
832 :
833 : /* numsrc >= (4G-140)/128 overflow in 32 bits */
834 0 : err = -ENOBUFS;
835 0 : if (n > sock_net(sk)->ipv4.sysctl_igmp_max_msf)
836 0 : goto out_free_gsf;
837 0 : err = set_mcast_msfilter(sk, gf32->gf_interface, n, gf32->gf_fmode,
838 0 : &gf32->gf_group, gf32->gf_slist);
839 0 : out_free_gsf:
840 0 : kfree(p);
841 0 : return err;
842 : }
843 :
844 0 : static int ip_mcast_join_leave(struct sock *sk, int optname,
845 : sockptr_t optval, int optlen)
846 : {
847 0 : struct ip_mreqn mreq = { };
848 0 : struct sockaddr_in *psin;
849 0 : struct group_req greq;
850 :
851 0 : if (optlen < sizeof(struct group_req))
852 : return -EINVAL;
853 0 : if (copy_from_sockptr(&greq, optval, sizeof(greq)))
854 : return -EFAULT;
855 :
856 0 : psin = (struct sockaddr_in *)&greq.gr_group;
857 0 : if (psin->sin_family != AF_INET)
858 : return -EINVAL;
859 0 : mreq.imr_multiaddr = psin->sin_addr;
860 0 : mreq.imr_ifindex = greq.gr_interface;
861 0 : if (optname == MCAST_JOIN_GROUP)
862 0 : return ip_mc_join_group(sk, &mreq);
863 0 : return ip_mc_leave_group(sk, &mreq);
864 : }
865 :
866 0 : static int compat_ip_mcast_join_leave(struct sock *sk, int optname,
867 : sockptr_t optval, int optlen)
868 : {
869 0 : struct compat_group_req greq;
870 0 : struct ip_mreqn mreq = { };
871 0 : struct sockaddr_in *psin;
872 :
873 0 : if (optlen < sizeof(struct compat_group_req))
874 : return -EINVAL;
875 0 : if (copy_from_sockptr(&greq, optval, sizeof(greq)))
876 : return -EFAULT;
877 :
878 0 : psin = (struct sockaddr_in *)&greq.gr_group;
879 0 : if (psin->sin_family != AF_INET)
880 : return -EINVAL;
881 0 : mreq.imr_multiaddr = psin->sin_addr;
882 0 : mreq.imr_ifindex = greq.gr_interface;
883 :
884 0 : if (optname == MCAST_JOIN_GROUP)
885 0 : return ip_mc_join_group(sk, &mreq);
886 0 : return ip_mc_leave_group(sk, &mreq);
887 : }
888 :
889 5 : static int do_ip_setsockopt(struct sock *sk, int level, int optname,
890 : sockptr_t optval, unsigned int optlen)
891 : {
892 5 : struct inet_sock *inet = inet_sk(sk);
893 5 : struct net *net = sock_net(sk);
894 5 : int val = 0, err;
895 5 : bool needs_rtnl = setsockopt_needs_rtnl(optname);
896 :
897 5 : switch (optname) {
898 5 : case IP_PKTINFO:
899 : case IP_RECVTTL:
900 : case IP_RECVOPTS:
901 : case IP_RECVTOS:
902 : case IP_RETOPTS:
903 : case IP_TOS:
904 : case IP_TTL:
905 : case IP_HDRINCL:
906 : case IP_MTU_DISCOVER:
907 : case IP_RECVERR:
908 : case IP_ROUTER_ALERT:
909 : case IP_FREEBIND:
910 : case IP_PASSSEC:
911 : case IP_TRANSPARENT:
912 : case IP_MINTTL:
913 : case IP_NODEFRAG:
914 : case IP_BIND_ADDRESS_NO_PORT:
915 : case IP_UNICAST_IF:
916 : case IP_MULTICAST_TTL:
917 : case IP_MULTICAST_ALL:
918 : case IP_MULTICAST_LOOP:
919 : case IP_RECVORIGDSTADDR:
920 : case IP_CHECKSUM:
921 : case IP_RECVFRAGSIZE:
922 : case IP_RECVERR_RFC4884:
923 5 : if (optlen >= sizeof(int)) {
924 5 : if (copy_from_sockptr(&val, optval, sizeof(val)))
925 : return -EFAULT;
926 0 : } else if (optlen >= sizeof(char)) {
927 0 : unsigned char ucval;
928 :
929 0 : if (copy_from_sockptr(&ucval, optval, sizeof(ucval)))
930 0 : return -EFAULT;
931 0 : val = (int) ucval;
932 : }
933 : }
934 :
935 : /* If optlen==0, it is equivalent to val == 0 */
936 :
937 5 : if (optname == IP_ROUTER_ALERT)
938 0 : return ip_ra_control(sk, val ? 1 : 0, NULL);
939 5 : if (ip_mroute_opt(optname))
940 : return ip_mroute_setsockopt(sk, optname, optval, optlen);
941 :
942 5 : err = 0;
943 5 : if (needs_rtnl)
944 0 : rtnl_lock();
945 5 : lock_sock(sk);
946 :
947 5 : switch (optname) {
948 0 : case IP_OPTIONS:
949 : {
950 0 : struct ip_options_rcu *old, *opt = NULL;
951 :
952 0 : if (optlen > 40)
953 0 : goto e_inval;
954 0 : err = ip_options_get(sock_net(sk), &opt, optval, optlen);
955 0 : if (err)
956 : break;
957 0 : old = rcu_dereference_protected(inet->inet_opt,
958 : lockdep_sock_is_held(sk));
959 0 : if (inet->is_icsk) {
960 0 : struct inet_connection_sock *icsk = inet_csk(sk);
961 : #if IS_ENABLED(CONFIG_IPV6)
962 : if (sk->sk_family == PF_INET ||
963 : (!((1 << sk->sk_state) &
964 : (TCPF_LISTEN | TCPF_CLOSE)) &&
965 : inet->inet_daddr != LOOPBACK4_IPV6)) {
966 : #endif
967 0 : if (old)
968 0 : icsk->icsk_ext_hdr_len -= old->opt.optlen;
969 0 : if (opt)
970 0 : icsk->icsk_ext_hdr_len += opt->opt.optlen;
971 0 : icsk->icsk_sync_mss(sk, icsk->icsk_pmtu_cookie);
972 : #if IS_ENABLED(CONFIG_IPV6)
973 : }
974 : #endif
975 : }
976 0 : rcu_assign_pointer(inet->inet_opt, opt);
977 0 : if (old)
978 0 : kfree_rcu(old, rcu);
979 : break;
980 : }
981 1 : case IP_PKTINFO:
982 1 : if (val)
983 1 : inet->cmsg_flags |= IP_CMSG_PKTINFO;
984 : else
985 0 : inet->cmsg_flags &= ~IP_CMSG_PKTINFO;
986 : break;
987 0 : case IP_RECVTTL:
988 0 : if (val)
989 0 : inet->cmsg_flags |= IP_CMSG_TTL;
990 : else
991 0 : inet->cmsg_flags &= ~IP_CMSG_TTL;
992 : break;
993 0 : case IP_RECVTOS:
994 0 : if (val)
995 0 : inet->cmsg_flags |= IP_CMSG_TOS;
996 : else
997 0 : inet->cmsg_flags &= ~IP_CMSG_TOS;
998 : break;
999 0 : case IP_RECVOPTS:
1000 0 : if (val)
1001 0 : inet->cmsg_flags |= IP_CMSG_RECVOPTS;
1002 : else
1003 0 : inet->cmsg_flags &= ~IP_CMSG_RECVOPTS;
1004 : break;
1005 0 : case IP_RETOPTS:
1006 0 : if (val)
1007 0 : inet->cmsg_flags |= IP_CMSG_RETOPTS;
1008 : else
1009 0 : inet->cmsg_flags &= ~IP_CMSG_RETOPTS;
1010 : break;
1011 0 : case IP_PASSSEC:
1012 0 : if (val)
1013 0 : inet->cmsg_flags |= IP_CMSG_PASSSEC;
1014 : else
1015 0 : inet->cmsg_flags &= ~IP_CMSG_PASSSEC;
1016 : break;
1017 0 : case IP_RECVORIGDSTADDR:
1018 0 : if (val)
1019 0 : inet->cmsg_flags |= IP_CMSG_ORIGDSTADDR;
1020 : else
1021 0 : inet->cmsg_flags &= ~IP_CMSG_ORIGDSTADDR;
1022 : break;
1023 0 : case IP_CHECKSUM:
1024 0 : if (val) {
1025 0 : if (!(inet->cmsg_flags & IP_CMSG_CHECKSUM)) {
1026 0 : inet_inc_convert_csum(sk);
1027 0 : inet->cmsg_flags |= IP_CMSG_CHECKSUM;
1028 : }
1029 : } else {
1030 0 : if (inet->cmsg_flags & IP_CMSG_CHECKSUM) {
1031 0 : inet_dec_convert_csum(sk);
1032 0 : inet->cmsg_flags &= ~IP_CMSG_CHECKSUM;
1033 : }
1034 : }
1035 : break;
1036 0 : case IP_RECVFRAGSIZE:
1037 0 : if (sk->sk_type != SOCK_RAW && sk->sk_type != SOCK_DGRAM)
1038 0 : goto e_inval;
1039 0 : if (val)
1040 0 : inet->cmsg_flags |= IP_CMSG_RECVFRAGSIZE;
1041 : else
1042 0 : inet->cmsg_flags &= ~IP_CMSG_RECVFRAGSIZE;
1043 : break;
1044 4 : case IP_TOS: /* This sets both TOS and Precedence */
1045 4 : __ip_sock_set_tos(sk, val);
1046 4 : break;
1047 0 : case IP_TTL:
1048 0 : if (optlen < 1)
1049 0 : goto e_inval;
1050 0 : if (val != -1 && (val < 1 || val > 255))
1051 0 : goto e_inval;
1052 0 : inet->uc_ttl = val;
1053 0 : break;
1054 0 : case IP_HDRINCL:
1055 0 : if (sk->sk_type != SOCK_RAW) {
1056 : err = -ENOPROTOOPT;
1057 : break;
1058 : }
1059 0 : inet->hdrincl = val ? 1 : 0;
1060 0 : break;
1061 0 : case IP_NODEFRAG:
1062 0 : if (sk->sk_type != SOCK_RAW) {
1063 : err = -ENOPROTOOPT;
1064 : break;
1065 : }
1066 0 : inet->nodefrag = val ? 1 : 0;
1067 0 : break;
1068 0 : case IP_BIND_ADDRESS_NO_PORT:
1069 0 : inet->bind_address_no_port = val ? 1 : 0;
1070 0 : break;
1071 0 : case IP_MTU_DISCOVER:
1072 0 : if (val < IP_PMTUDISC_DONT || val > IP_PMTUDISC_OMIT)
1073 0 : goto e_inval;
1074 0 : inet->pmtudisc = val;
1075 0 : break;
1076 0 : case IP_RECVERR:
1077 0 : inet->recverr = !!val;
1078 0 : if (!val)
1079 0 : skb_queue_purge(&sk->sk_error_queue);
1080 : break;
1081 0 : case IP_RECVERR_RFC4884:
1082 0 : if (val < 0 || val > 1)
1083 0 : goto e_inval;
1084 0 : inet->recverr_rfc4884 = !!val;
1085 0 : break;
1086 0 : case IP_MULTICAST_TTL:
1087 0 : if (sk->sk_type == SOCK_STREAM)
1088 0 : goto e_inval;
1089 0 : if (optlen < 1)
1090 0 : goto e_inval;
1091 0 : if (val == -1)
1092 0 : val = 1;
1093 0 : if (val < 0 || val > 255)
1094 0 : goto e_inval;
1095 0 : inet->mc_ttl = val;
1096 0 : break;
1097 0 : case IP_MULTICAST_LOOP:
1098 0 : if (optlen < 1)
1099 0 : goto e_inval;
1100 0 : inet->mc_loop = !!val;
1101 0 : break;
1102 0 : case IP_UNICAST_IF:
1103 : {
1104 0 : struct net_device *dev = NULL;
1105 0 : int ifindex;
1106 0 : int midx;
1107 :
1108 0 : if (optlen != sizeof(int))
1109 0 : goto e_inval;
1110 :
1111 0 : ifindex = (__force int)ntohl((__force __be32)val);
1112 0 : if (ifindex == 0) {
1113 0 : inet->uc_index = 0;
1114 0 : err = 0;
1115 0 : break;
1116 : }
1117 :
1118 0 : dev = dev_get_by_index(sock_net(sk), ifindex);
1119 0 : err = -EADDRNOTAVAIL;
1120 0 : if (!dev)
1121 : break;
1122 :
1123 0 : midx = l3mdev_master_ifindex(dev);
1124 0 : dev_put(dev);
1125 :
1126 0 : err = -EINVAL;
1127 0 : if (sk->sk_bound_dev_if && midx != sk->sk_bound_dev_if)
1128 : break;
1129 :
1130 0 : inet->uc_index = ifindex;
1131 0 : err = 0;
1132 0 : break;
1133 : }
1134 0 : case IP_MULTICAST_IF:
1135 : {
1136 0 : struct ip_mreqn mreq;
1137 0 : struct net_device *dev = NULL;
1138 0 : int midx;
1139 :
1140 0 : if (sk->sk_type == SOCK_STREAM)
1141 0 : goto e_inval;
1142 : /*
1143 : * Check the arguments are allowable
1144 : */
1145 :
1146 0 : if (optlen < sizeof(struct in_addr))
1147 0 : goto e_inval;
1148 :
1149 0 : err = -EFAULT;
1150 0 : if (optlen >= sizeof(struct ip_mreqn)) {
1151 0 : if (copy_from_sockptr(&mreq, optval, sizeof(mreq)))
1152 : break;
1153 : } else {
1154 0 : memset(&mreq, 0, sizeof(mreq));
1155 0 : if (optlen >= sizeof(struct ip_mreq)) {
1156 0 : if (copy_from_sockptr(&mreq, optval,
1157 : sizeof(struct ip_mreq)))
1158 : break;
1159 0 : } else if (optlen >= sizeof(struct in_addr)) {
1160 0 : if (copy_from_sockptr(&mreq.imr_address, optval,
1161 : sizeof(struct in_addr)))
1162 : break;
1163 : }
1164 : }
1165 :
1166 0 : if (!mreq.imr_ifindex) {
1167 0 : if (mreq.imr_address.s_addr == htonl(INADDR_ANY)) {
1168 0 : inet->mc_index = 0;
1169 0 : inet->mc_addr = 0;
1170 0 : err = 0;
1171 0 : break;
1172 : }
1173 0 : dev = ip_dev_find(sock_net(sk), mreq.imr_address.s_addr);
1174 0 : if (dev)
1175 0 : mreq.imr_ifindex = dev->ifindex;
1176 : } else
1177 0 : dev = dev_get_by_index(sock_net(sk), mreq.imr_ifindex);
1178 :
1179 :
1180 0 : err = -EADDRNOTAVAIL;
1181 0 : if (!dev)
1182 : break;
1183 :
1184 0 : midx = l3mdev_master_ifindex(dev);
1185 :
1186 0 : dev_put(dev);
1187 :
1188 0 : err = -EINVAL;
1189 0 : if (sk->sk_bound_dev_if &&
1190 0 : mreq.imr_ifindex != sk->sk_bound_dev_if &&
1191 : midx != sk->sk_bound_dev_if)
1192 : break;
1193 :
1194 0 : inet->mc_index = mreq.imr_ifindex;
1195 0 : inet->mc_addr = mreq.imr_address.s_addr;
1196 0 : err = 0;
1197 0 : break;
1198 : }
1199 :
1200 0 : case IP_ADD_MEMBERSHIP:
1201 : case IP_DROP_MEMBERSHIP:
1202 : {
1203 0 : struct ip_mreqn mreq;
1204 :
1205 0 : err = -EPROTO;
1206 0 : if (inet_sk(sk)->is_icsk)
1207 : break;
1208 :
1209 0 : if (optlen < sizeof(struct ip_mreq))
1210 0 : goto e_inval;
1211 0 : err = -EFAULT;
1212 0 : if (optlen >= sizeof(struct ip_mreqn)) {
1213 0 : if (copy_from_sockptr(&mreq, optval, sizeof(mreq)))
1214 : break;
1215 : } else {
1216 0 : memset(&mreq, 0, sizeof(mreq));
1217 0 : if (copy_from_sockptr(&mreq, optval,
1218 : sizeof(struct ip_mreq)))
1219 : break;
1220 : }
1221 :
1222 0 : if (optname == IP_ADD_MEMBERSHIP)
1223 0 : err = ip_mc_join_group(sk, &mreq);
1224 : else
1225 0 : err = ip_mc_leave_group(sk, &mreq);
1226 : break;
1227 : }
1228 0 : case IP_MSFILTER:
1229 : {
1230 0 : struct ip_msfilter *msf;
1231 :
1232 0 : if (optlen < IP_MSFILTER_SIZE(0))
1233 0 : goto e_inval;
1234 0 : if (optlen > sysctl_optmem_max) {
1235 : err = -ENOBUFS;
1236 : break;
1237 : }
1238 0 : msf = memdup_sockptr(optval, optlen);
1239 0 : if (IS_ERR(msf)) {
1240 0 : err = PTR_ERR(msf);
1241 0 : break;
1242 : }
1243 : /* numsrc >= (1G-4) overflow in 32 bits */
1244 0 : if (msf->imsf_numsrc >= 0x3ffffffcU ||
1245 0 : msf->imsf_numsrc > net->ipv4.sysctl_igmp_max_msf) {
1246 0 : kfree(msf);
1247 0 : err = -ENOBUFS;
1248 0 : break;
1249 : }
1250 0 : if (IP_MSFILTER_SIZE(msf->imsf_numsrc) > optlen) {
1251 0 : kfree(msf);
1252 0 : err = -EINVAL;
1253 0 : break;
1254 : }
1255 0 : err = ip_mc_msfilter(sk, msf, 0);
1256 0 : kfree(msf);
1257 0 : break;
1258 : }
1259 0 : case IP_BLOCK_SOURCE:
1260 : case IP_UNBLOCK_SOURCE:
1261 : case IP_ADD_SOURCE_MEMBERSHIP:
1262 : case IP_DROP_SOURCE_MEMBERSHIP:
1263 : {
1264 0 : struct ip_mreq_source mreqs;
1265 0 : int omode, add;
1266 :
1267 0 : if (optlen != sizeof(struct ip_mreq_source))
1268 0 : goto e_inval;
1269 0 : if (copy_from_sockptr(&mreqs, optval, sizeof(mreqs))) {
1270 : err = -EFAULT;
1271 0 : break;
1272 : }
1273 0 : if (optname == IP_BLOCK_SOURCE) {
1274 : omode = MCAST_EXCLUDE;
1275 : add = 1;
1276 0 : } else if (optname == IP_UNBLOCK_SOURCE) {
1277 : omode = MCAST_EXCLUDE;
1278 : add = 0;
1279 0 : } else if (optname == IP_ADD_SOURCE_MEMBERSHIP) {
1280 0 : struct ip_mreqn mreq;
1281 :
1282 0 : mreq.imr_multiaddr.s_addr = mreqs.imr_multiaddr;
1283 0 : mreq.imr_address.s_addr = mreqs.imr_interface;
1284 0 : mreq.imr_ifindex = 0;
1285 0 : err = ip_mc_join_group_ssm(sk, &mreq, MCAST_INCLUDE);
1286 0 : if (err && err != -EADDRINUSE)
1287 : break;
1288 0 : omode = MCAST_INCLUDE;
1289 0 : add = 1;
1290 : } else /* IP_DROP_SOURCE_MEMBERSHIP */ {
1291 : omode = MCAST_INCLUDE;
1292 : add = 0;
1293 : }
1294 0 : err = ip_mc_source(add, omode, sk, &mreqs, 0);
1295 0 : break;
1296 : }
1297 : case MCAST_JOIN_GROUP:
1298 : case MCAST_LEAVE_GROUP:
1299 0 : if (in_compat_syscall())
1300 0 : err = compat_ip_mcast_join_leave(sk, optname, optval,
1301 : optlen);
1302 : else
1303 0 : err = ip_mcast_join_leave(sk, optname, optval, optlen);
1304 : break;
1305 0 : case MCAST_JOIN_SOURCE_GROUP:
1306 : case MCAST_LEAVE_SOURCE_GROUP:
1307 : case MCAST_BLOCK_SOURCE:
1308 : case MCAST_UNBLOCK_SOURCE:
1309 0 : err = do_mcast_group_source(sk, optname, optval, optlen);
1310 0 : break;
1311 : case MCAST_MSFILTER:
1312 0 : if (in_compat_syscall())
1313 0 : err = compat_ip_set_mcast_msfilter(sk, optval, optlen);
1314 : else
1315 0 : err = ip_set_mcast_msfilter(sk, optval, optlen);
1316 : break;
1317 0 : case IP_MULTICAST_ALL:
1318 0 : if (optlen < 1)
1319 0 : goto e_inval;
1320 0 : if (val != 0 && val != 1)
1321 0 : goto e_inval;
1322 0 : inet->mc_all = val;
1323 0 : break;
1324 :
1325 0 : case IP_FREEBIND:
1326 0 : if (optlen < 1)
1327 0 : goto e_inval;
1328 0 : inet->freebind = !!val;
1329 0 : break;
1330 :
1331 0 : case IP_IPSEC_POLICY:
1332 : case IP_XFRM_POLICY:
1333 0 : err = -EPERM;
1334 0 : if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN))
1335 : break;
1336 0 : err = xfrm_user_policy(sk, optname, optval, optlen);
1337 0 : break;
1338 :
1339 0 : case IP_TRANSPARENT:
1340 0 : if (!!val && !ns_capable(sock_net(sk)->user_ns, CAP_NET_RAW) &&
1341 0 : !ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN)) {
1342 : err = -EPERM;
1343 : break;
1344 : }
1345 0 : if (optlen < 1)
1346 0 : goto e_inval;
1347 0 : inet->transparent = !!val;
1348 0 : break;
1349 :
1350 0 : case IP_MINTTL:
1351 0 : if (optlen < 1)
1352 0 : goto e_inval;
1353 0 : if (val < 0 || val > 255)
1354 0 : goto e_inval;
1355 0 : inet->min_ttl = val;
1356 0 : break;
1357 :
1358 : default:
1359 : err = -ENOPROTOOPT;
1360 : break;
1361 : }
1362 5 : release_sock(sk);
1363 5 : if (needs_rtnl)
1364 0 : rtnl_unlock();
1365 : return err;
1366 :
1367 0 : e_inval:
1368 0 : release_sock(sk);
1369 0 : if (needs_rtnl)
1370 0 : rtnl_unlock();
1371 : return -EINVAL;
1372 : }
1373 :
1374 : /**
1375 : * ipv4_pktinfo_prepare - transfer some info from rtable to skb
1376 : * @sk: socket
1377 : * @skb: buffer
1378 : *
1379 : * To support IP_CMSG_PKTINFO option, we store rt_iif and specific
1380 : * destination in skb->cb[] before dst drop.
1381 : * This way, receiver doesn't make cache line misses to read rtable.
1382 : */
1383 2 : void ipv4_pktinfo_prepare(const struct sock *sk, struct sk_buff *skb)
1384 : {
1385 2 : struct in_pktinfo *pktinfo = PKTINFO_SKB_CB(skb);
1386 2 : bool prepare = (inet_sk(sk)->cmsg_flags & IP_CMSG_PKTINFO) ||
1387 : ipv6_sk_rxinfo(sk);
1388 :
1389 2 : if (prepare && skb_rtable(skb)) {
1390 : /* skb->cb is overloaded: prior to this point it is IP{6}CB
1391 : * which has interface index (iif) as the first member of the
1392 : * underlying inet{6}_skb_parm struct. This code then overlays
1393 : * PKTINFO_SKB_CB and in_pktinfo also has iif as the first
1394 : * element so the iif is picked up from the prior IPCB. If iif
1395 : * is the loopback interface, then return the sending interface
1396 : * (e.g., process binds socket to eth0 for Tx which is
1397 : * redirected to loopback in the rtable/dst).
1398 : */
1399 0 : struct rtable *rt = skb_rtable(skb);
1400 0 : bool l3slave = ipv4_l3mdev_skb(IPCB(skb)->flags);
1401 :
1402 0 : if (pktinfo->ipi_ifindex == LOOPBACK_IFINDEX)
1403 0 : pktinfo->ipi_ifindex = inet_iif(skb);
1404 0 : else if (l3slave && rt && rt->rt_iif)
1405 0 : pktinfo->ipi_ifindex = rt->rt_iif;
1406 :
1407 0 : pktinfo->ipi_spec_dst.s_addr = fib_compute_spec_dst(skb);
1408 : } else {
1409 2 : pktinfo->ipi_ifindex = 0;
1410 2 : pktinfo->ipi_spec_dst.s_addr = 0;
1411 : }
1412 2 : skb_dst_drop(skb);
1413 2 : }
1414 :
1415 5 : int ip_setsockopt(struct sock *sk, int level, int optname, sockptr_t optval,
1416 : unsigned int optlen)
1417 : {
1418 5 : int err;
1419 :
1420 5 : if (level != SOL_IP)
1421 : return -ENOPROTOOPT;
1422 :
1423 5 : err = do_ip_setsockopt(sk, level, optname, optval, optlen);
1424 : #if IS_ENABLED(CONFIG_BPFILTER_UMH)
1425 : if (optname >= BPFILTER_IPT_SO_SET_REPLACE &&
1426 : optname < BPFILTER_IPT_SET_MAX)
1427 : err = bpfilter_ip_set_sockopt(sk, optname, optval, optlen);
1428 : #endif
1429 : #ifdef CONFIG_NETFILTER
1430 : /* we need to exclude all possible ENOPROTOOPTs except default case */
1431 5 : if (err == -ENOPROTOOPT && optname != IP_HDRINCL &&
1432 0 : optname != IP_IPSEC_POLICY &&
1433 : optname != IP_XFRM_POLICY &&
1434 0 : !ip_mroute_opt(optname))
1435 0 : err = nf_setsockopt(sk, PF_INET, optname, optval, optlen);
1436 : #endif
1437 : return err;
1438 : }
1439 : EXPORT_SYMBOL(ip_setsockopt);
1440 :
1441 : /*
1442 : * Get the options. Note for future reference. The GET of IP options gets
1443 : * the _received_ ones. The set sets the _sent_ ones.
1444 : */
1445 :
1446 4 : static bool getsockopt_needs_rtnl(int optname)
1447 : {
1448 4 : switch (optname) {
1449 : case IP_MSFILTER:
1450 : case MCAST_MSFILTER:
1451 : return true;
1452 : }
1453 4 : return false;
1454 : }
1455 :
1456 0 : static int ip_get_mcast_msfilter(struct sock *sk, void __user *optval,
1457 : int __user *optlen, int len)
1458 : {
1459 0 : const int size0 = offsetof(struct group_filter, gf_slist);
1460 0 : struct group_filter __user *p = optval;
1461 0 : struct group_filter gsf;
1462 0 : int num;
1463 0 : int err;
1464 :
1465 0 : if (len < size0)
1466 : return -EINVAL;
1467 0 : if (copy_from_user(&gsf, p, size0))
1468 : return -EFAULT;
1469 :
1470 0 : num = gsf.gf_numsrc;
1471 0 : err = ip_mc_gsfget(sk, &gsf, p->gf_slist);
1472 0 : if (err)
1473 : return err;
1474 0 : if (gsf.gf_numsrc < num)
1475 : num = gsf.gf_numsrc;
1476 0 : if (put_user(GROUP_FILTER_SIZE(num), optlen) ||
1477 0 : copy_to_user(p, &gsf, size0))
1478 0 : return -EFAULT;
1479 : return 0;
1480 : }
1481 :
1482 0 : static int compat_ip_get_mcast_msfilter(struct sock *sk, void __user *optval,
1483 : int __user *optlen, int len)
1484 : {
1485 0 : const int size0 = offsetof(struct compat_group_filter, gf_slist);
1486 0 : struct compat_group_filter __user *p = optval;
1487 0 : struct compat_group_filter gf32;
1488 0 : struct group_filter gf;
1489 0 : int num;
1490 0 : int err;
1491 :
1492 0 : if (len < size0)
1493 : return -EINVAL;
1494 0 : if (copy_from_user(&gf32, p, size0))
1495 : return -EFAULT;
1496 :
1497 0 : gf.gf_interface = gf32.gf_interface;
1498 0 : gf.gf_fmode = gf32.gf_fmode;
1499 0 : num = gf.gf_numsrc = gf32.gf_numsrc;
1500 0 : gf.gf_group = gf32.gf_group;
1501 :
1502 0 : err = ip_mc_gsfget(sk, &gf, p->gf_slist);
1503 0 : if (err)
1504 : return err;
1505 0 : if (gf.gf_numsrc < num)
1506 : num = gf.gf_numsrc;
1507 0 : len = GROUP_FILTER_SIZE(num) - (sizeof(gf) - sizeof(gf32));
1508 0 : if (put_user(len, optlen) ||
1509 0 : put_user(gf.gf_fmode, &p->gf_fmode) ||
1510 0 : put_user(gf.gf_numsrc, &p->gf_numsrc))
1511 0 : return -EFAULT;
1512 : return 0;
1513 : }
1514 :
1515 4 : static int do_ip_getsockopt(struct sock *sk, int level, int optname,
1516 : char __user *optval, int __user *optlen)
1517 : {
1518 4 : struct inet_sock *inet = inet_sk(sk);
1519 4 : bool needs_rtnl = getsockopt_needs_rtnl(optname);
1520 4 : int val, err = 0;
1521 4 : int len;
1522 :
1523 4 : if (level != SOL_IP)
1524 : return -EOPNOTSUPP;
1525 :
1526 4 : if (ip_mroute_opt(optname))
1527 : return ip_mroute_getsockopt(sk, optname, optval, optlen);
1528 :
1529 4 : if (get_user(len, optlen))
1530 : return -EFAULT;
1531 4 : if (len < 0)
1532 : return -EINVAL;
1533 :
1534 4 : if (needs_rtnl)
1535 0 : rtnl_lock();
1536 4 : lock_sock(sk);
1537 :
1538 4 : switch (optname) {
1539 4 : case IP_OPTIONS:
1540 : {
1541 4 : unsigned char optbuf[sizeof(struct ip_options)+40];
1542 4 : struct ip_options *opt = (struct ip_options *)optbuf;
1543 4 : struct ip_options_rcu *inet_opt;
1544 :
1545 4 : inet_opt = rcu_dereference_protected(inet->inet_opt,
1546 : lockdep_sock_is_held(sk));
1547 4 : opt->optlen = 0;
1548 4 : if (inet_opt)
1549 0 : memcpy(optbuf, &inet_opt->opt,
1550 : sizeof(struct ip_options) +
1551 0 : inet_opt->opt.optlen);
1552 4 : release_sock(sk);
1553 :
1554 4 : if (opt->optlen == 0)
1555 4 : return put_user(0, optlen);
1556 :
1557 0 : ip_options_undo(opt);
1558 :
1559 0 : len = min_t(unsigned int, len, opt->optlen);
1560 0 : if (put_user(len, optlen))
1561 : return -EFAULT;
1562 0 : if (copy_to_user(optval, opt->__data, len))
1563 0 : return -EFAULT;
1564 : return 0;
1565 : }
1566 0 : case IP_PKTINFO:
1567 0 : val = (inet->cmsg_flags & IP_CMSG_PKTINFO) != 0;
1568 0 : break;
1569 0 : case IP_RECVTTL:
1570 0 : val = (inet->cmsg_flags & IP_CMSG_TTL) != 0;
1571 0 : break;
1572 0 : case IP_RECVTOS:
1573 0 : val = (inet->cmsg_flags & IP_CMSG_TOS) != 0;
1574 0 : break;
1575 0 : case IP_RECVOPTS:
1576 0 : val = (inet->cmsg_flags & IP_CMSG_RECVOPTS) != 0;
1577 0 : break;
1578 0 : case IP_RETOPTS:
1579 0 : val = (inet->cmsg_flags & IP_CMSG_RETOPTS) != 0;
1580 0 : break;
1581 0 : case IP_PASSSEC:
1582 0 : val = (inet->cmsg_flags & IP_CMSG_PASSSEC) != 0;
1583 0 : break;
1584 0 : case IP_RECVORIGDSTADDR:
1585 0 : val = (inet->cmsg_flags & IP_CMSG_ORIGDSTADDR) != 0;
1586 0 : break;
1587 0 : case IP_CHECKSUM:
1588 0 : val = (inet->cmsg_flags & IP_CMSG_CHECKSUM) != 0;
1589 0 : break;
1590 0 : case IP_RECVFRAGSIZE:
1591 0 : val = (inet->cmsg_flags & IP_CMSG_RECVFRAGSIZE) != 0;
1592 0 : break;
1593 0 : case IP_TOS:
1594 0 : val = inet->tos;
1595 0 : break;
1596 : case IP_TTL:
1597 : {
1598 0 : struct net *net = sock_net(sk);
1599 0 : val = (inet->uc_ttl == -1 ?
1600 0 : net->ipv4.sysctl_ip_default_ttl :
1601 : inet->uc_ttl);
1602 0 : break;
1603 : }
1604 0 : case IP_HDRINCL:
1605 0 : val = inet->hdrincl;
1606 0 : break;
1607 0 : case IP_NODEFRAG:
1608 0 : val = inet->nodefrag;
1609 0 : break;
1610 0 : case IP_BIND_ADDRESS_NO_PORT:
1611 0 : val = inet->bind_address_no_port;
1612 0 : break;
1613 0 : case IP_MTU_DISCOVER:
1614 0 : val = inet->pmtudisc;
1615 0 : break;
1616 0 : case IP_MTU:
1617 : {
1618 0 : struct dst_entry *dst;
1619 0 : val = 0;
1620 0 : dst = sk_dst_get(sk);
1621 0 : if (dst) {
1622 0 : val = dst_mtu(dst);
1623 0 : dst_release(dst);
1624 : }
1625 0 : if (!val) {
1626 0 : release_sock(sk);
1627 0 : return -ENOTCONN;
1628 : }
1629 : break;
1630 : }
1631 0 : case IP_RECVERR:
1632 0 : val = inet->recverr;
1633 0 : break;
1634 0 : case IP_RECVERR_RFC4884:
1635 0 : val = inet->recverr_rfc4884;
1636 0 : break;
1637 0 : case IP_MULTICAST_TTL:
1638 0 : val = inet->mc_ttl;
1639 0 : break;
1640 0 : case IP_MULTICAST_LOOP:
1641 0 : val = inet->mc_loop;
1642 0 : break;
1643 0 : case IP_UNICAST_IF:
1644 0 : val = (__force int)htonl((__u32) inet->uc_index);
1645 0 : break;
1646 0 : case IP_MULTICAST_IF:
1647 : {
1648 0 : struct in_addr addr;
1649 0 : len = min_t(unsigned int, len, sizeof(struct in_addr));
1650 0 : addr.s_addr = inet->mc_addr;
1651 0 : release_sock(sk);
1652 :
1653 0 : if (put_user(len, optlen))
1654 : return -EFAULT;
1655 0 : if (copy_to_user(optval, &addr, len))
1656 0 : return -EFAULT;
1657 : return 0;
1658 : }
1659 0 : case IP_MSFILTER:
1660 : {
1661 0 : struct ip_msfilter msf;
1662 :
1663 0 : if (len < IP_MSFILTER_SIZE(0)) {
1664 0 : err = -EINVAL;
1665 0 : goto out;
1666 : }
1667 0 : if (copy_from_user(&msf, optval, IP_MSFILTER_SIZE(0))) {
1668 0 : err = -EFAULT;
1669 0 : goto out;
1670 : }
1671 0 : err = ip_mc_msfget(sk, &msf,
1672 : (struct ip_msfilter __user *)optval, optlen);
1673 0 : goto out;
1674 : }
1675 : case MCAST_MSFILTER:
1676 0 : if (in_compat_syscall())
1677 0 : err = compat_ip_get_mcast_msfilter(sk, optval, optlen,
1678 : len);
1679 : else
1680 0 : err = ip_get_mcast_msfilter(sk, optval, optlen, len);
1681 0 : goto out;
1682 0 : case IP_MULTICAST_ALL:
1683 0 : val = inet->mc_all;
1684 0 : break;
1685 0 : case IP_PKTOPTIONS:
1686 : {
1687 0 : struct msghdr msg;
1688 :
1689 0 : release_sock(sk);
1690 :
1691 0 : if (sk->sk_type != SOCK_STREAM)
1692 : return -ENOPROTOOPT;
1693 :
1694 0 : msg.msg_control_is_user = true;
1695 0 : msg.msg_control_user = optval;
1696 0 : msg.msg_controllen = len;
1697 0 : msg.msg_flags = in_compat_syscall() ? MSG_CMSG_COMPAT : 0;
1698 :
1699 0 : if (inet->cmsg_flags & IP_CMSG_PKTINFO) {
1700 0 : struct in_pktinfo info;
1701 :
1702 0 : info.ipi_addr.s_addr = inet->inet_rcv_saddr;
1703 0 : info.ipi_spec_dst.s_addr = inet->inet_rcv_saddr;
1704 0 : info.ipi_ifindex = inet->mc_index;
1705 0 : put_cmsg(&msg, SOL_IP, IP_PKTINFO, sizeof(info), &info);
1706 : }
1707 0 : if (inet->cmsg_flags & IP_CMSG_TTL) {
1708 0 : int hlim = inet->mc_ttl;
1709 0 : put_cmsg(&msg, SOL_IP, IP_TTL, sizeof(hlim), &hlim);
1710 : }
1711 0 : if (inet->cmsg_flags & IP_CMSG_TOS) {
1712 0 : int tos = inet->rcv_tos;
1713 0 : put_cmsg(&msg, SOL_IP, IP_TOS, sizeof(tos), &tos);
1714 : }
1715 0 : len -= msg.msg_controllen;
1716 0 : return put_user(len, optlen);
1717 : }
1718 0 : case IP_FREEBIND:
1719 0 : val = inet->freebind;
1720 0 : break;
1721 0 : case IP_TRANSPARENT:
1722 0 : val = inet->transparent;
1723 0 : break;
1724 0 : case IP_MINTTL:
1725 0 : val = inet->min_ttl;
1726 0 : break;
1727 0 : default:
1728 0 : release_sock(sk);
1729 0 : return -ENOPROTOOPT;
1730 : }
1731 0 : release_sock(sk);
1732 :
1733 0 : if (len < sizeof(int) && len > 0 && val >= 0 && val <= 255) {
1734 0 : unsigned char ucval = (unsigned char)val;
1735 0 : len = 1;
1736 0 : if (put_user(len, optlen))
1737 0 : return -EFAULT;
1738 0 : if (copy_to_user(optval, &ucval, 1))
1739 : return -EFAULT;
1740 : } else {
1741 0 : len = min_t(unsigned int, sizeof(int), len);
1742 0 : if (put_user(len, optlen))
1743 : return -EFAULT;
1744 0 : if (copy_to_user(optval, &val, len))
1745 0 : return -EFAULT;
1746 : }
1747 : return 0;
1748 :
1749 0 : out:
1750 0 : release_sock(sk);
1751 0 : if (needs_rtnl)
1752 0 : rtnl_unlock();
1753 : return err;
1754 : }
1755 :
1756 4 : int ip_getsockopt(struct sock *sk, int level,
1757 : int optname, char __user *optval, int __user *optlen)
1758 : {
1759 4 : int err;
1760 :
1761 4 : err = do_ip_getsockopt(sk, level, optname, optval, optlen);
1762 :
1763 : #if IS_ENABLED(CONFIG_BPFILTER_UMH)
1764 : if (optname >= BPFILTER_IPT_SO_GET_INFO &&
1765 : optname < BPFILTER_IPT_GET_MAX)
1766 : err = bpfilter_ip_get_sockopt(sk, optname, optval, optlen);
1767 : #endif
1768 : #ifdef CONFIG_NETFILTER
1769 : /* we need to exclude all possible ENOPROTOOPTs except default case */
1770 4 : if (err == -ENOPROTOOPT && optname != IP_PKTOPTIONS &&
1771 0 : !ip_mroute_opt(optname)) {
1772 0 : int len;
1773 :
1774 0 : if (get_user(len, optlen))
1775 : return -EFAULT;
1776 :
1777 0 : err = nf_getsockopt(sk, PF_INET, optname, optval, &len);
1778 0 : if (err >= 0)
1779 0 : err = put_user(len, optlen);
1780 0 : return err;
1781 : }
1782 : #endif
1783 : return err;
1784 : }
1785 : EXPORT_SYMBOL(ip_getsockopt);
|