hc
2024-05-10 748e4f3d702def1a4bff191e0cf93b6a05340f01
kernel/net/ipv4/ip_sockglue.c
....@@ -280,7 +280,8 @@
280280 err = cmsg->cmsg_len - sizeof(struct cmsghdr);
281281
282282 /* Our caller is responsible for freeing ipc->opt */
283
- err = ip_options_get(net, &ipc->opt, CMSG_DATA(cmsg),
283
+ err = ip_options_get(net, &ipc->opt,
284
+ KERNEL_SOCKPTR(CMSG_DATA(cmsg)),
284285 err < 40 ? err : 40);
285286 if (err)
286287 return err;
....@@ -316,7 +317,14 @@
316317 ipc->tos = val;
317318 ipc->priority = rt_tos2priority(ipc->tos);
318319 break;
319
-
320
+ case IP_PROTOCOL:
321
+ if (cmsg->cmsg_len != CMSG_LEN(sizeof(int)))
322
+ return -EINVAL;
323
+ val = *(int *)CMSG_DATA(cmsg);
324
+ if (val < 1 || val > 255)
325
+ return -EINVAL;
326
+ ipc->protocol = val;
327
+ break;
320328 default:
321329 return -EINVAL;
322330 }
....@@ -343,6 +351,8 @@
343351 return -EINVAL;
344352
345353 new_ra = on ? kmalloc(sizeof(*new_ra), GFP_KERNEL) : NULL;
354
+ if (on && !new_ra)
355
+ return -ENOMEM;
346356
347357 mutex_lock(&net->ipv4.ra_mutex);
348358 for (rap = &net->ipv4.ra_chain;
....@@ -387,6 +397,18 @@
387397 return 0;
388398 }
389399
400
+static void ipv4_icmp_error_rfc4884(const struct sk_buff *skb,
401
+ struct sock_ee_data_rfc4884 *out)
402
+{
403
+ switch (icmp_hdr(skb)->type) {
404
+ case ICMP_DEST_UNREACH:
405
+ case ICMP_TIME_EXCEEDED:
406
+ case ICMP_PARAMETERPROB:
407
+ ip_icmp_error_rfc4884(skb, out, sizeof(struct icmphdr),
408
+ icmp_hdr(skb)->un.reserved[1] * 4);
409
+ }
410
+}
411
+
390412 void ip_icmp_error(struct sock *sk, struct sk_buff *skb, int err,
391413 __be16 port, u32 info, u8 *payload)
392414 {
....@@ -409,6 +431,9 @@
409431 serr->port = port;
410432
411433 if (skb_pull(skb, payload - skb->data)) {
434
+ if (inet_sk(sk)->recverr_rfc4884)
435
+ ipv4_icmp_error_rfc4884(skb, &serr->ee.ee_rfc4884);
436
+
412437 skb_reset_transport_header(skb);
413438 if (sock_queue_err_skb(sk, skb) == 0)
414439 return;
....@@ -558,6 +583,61 @@
558583 return err;
559584 }
560585
586
+static void __ip_sock_set_tos(struct sock *sk, int val)
587
+{
588
+ if (sk->sk_type == SOCK_STREAM) {
589
+ val &= ~INET_ECN_MASK;
590
+ val |= inet_sk(sk)->tos & INET_ECN_MASK;
591
+ }
592
+ if (inet_sk(sk)->tos != val) {
593
+ inet_sk(sk)->tos = val;
594
+ sk->sk_priority = rt_tos2priority(val);
595
+ sk_dst_reset(sk);
596
+ }
597
+}
598
+
599
+void ip_sock_set_tos(struct sock *sk, int val)
600
+{
601
+ lock_sock(sk);
602
+ __ip_sock_set_tos(sk, val);
603
+ release_sock(sk);
604
+}
605
+EXPORT_SYMBOL(ip_sock_set_tos);
606
+
607
+void ip_sock_set_freebind(struct sock *sk)
608
+{
609
+ lock_sock(sk);
610
+ inet_sk(sk)->freebind = true;
611
+ release_sock(sk);
612
+}
613
+EXPORT_SYMBOL(ip_sock_set_freebind);
614
+
615
+void ip_sock_set_recverr(struct sock *sk)
616
+{
617
+ lock_sock(sk);
618
+ inet_sk(sk)->recverr = true;
619
+ release_sock(sk);
620
+}
621
+EXPORT_SYMBOL(ip_sock_set_recverr);
622
+
623
+int ip_sock_set_mtu_discover(struct sock *sk, int val)
624
+{
625
+ if (val < IP_PMTUDISC_DONT || val > IP_PMTUDISC_OMIT)
626
+ return -EINVAL;
627
+ lock_sock(sk);
628
+ inet_sk(sk)->pmtudisc = val;
629
+ release_sock(sk);
630
+ return 0;
631
+}
632
+EXPORT_SYMBOL(ip_sock_set_mtu_discover);
633
+
634
+void ip_sock_set_pktinfo(struct sock *sk)
635
+{
636
+ lock_sock(sk);
637
+ inet_sk(sk)->cmsg_flags |= IP_CMSG_PKTINFO;
638
+ release_sock(sk);
639
+}
640
+EXPORT_SYMBOL(ip_sock_set_pktinfo);
561641
562642 /*
563643 * Socket option code for IP. This is the end of the line after any
....@@ -585,8 +665,236 @@
585665 return false;
586666 }
587667
588
-static int do_ip_setsockopt(struct sock *sk, int level,
589
- int optname, char __user *optval, unsigned int optlen)
668
+static int set_mcast_msfilter(struct sock *sk, int ifindex,
669
+ int numsrc, int fmode,
670
+ struct sockaddr_storage *group,
671
+ struct sockaddr_storage *list)
672
+{
673
+ int msize = IP_MSFILTER_SIZE(numsrc);
674
+ struct ip_msfilter *msf;
675
+ struct sockaddr_in *psin;
676
+ int err, i;
677
+
678
+ msf = kmalloc(msize, GFP_KERNEL);
679
+ if (!msf)
680
+ return -ENOBUFS;
681
+
682
+ psin = (struct sockaddr_in *)group;
683
+ if (psin->sin_family != AF_INET)
684
+ goto Eaddrnotavail;
685
+ msf->imsf_multiaddr = psin->sin_addr.s_addr;
686
+ msf->imsf_interface = 0;
687
+ msf->imsf_fmode = fmode;
688
+ msf->imsf_numsrc = numsrc;
689
+ for (i = 0; i < numsrc; ++i) {
690
+ psin = (struct sockaddr_in *)&list[i];
691
+
692
+ if (psin->sin_family != AF_INET)
693
+ goto Eaddrnotavail;
694
+ msf->imsf_slist[i] = psin->sin_addr.s_addr;
695
+ }
696
+ err = ip_mc_msfilter(sk, msf, ifindex);
697
+ kfree(msf);
698
+ return err;
699
+
700
+Eaddrnotavail:
701
+ kfree(msf);
702
+ return -EADDRNOTAVAIL;
703
+}
704
+
705
+static int copy_group_source_from_sockptr(struct group_source_req *greqs,
706
+ sockptr_t optval, int optlen)
707
+{
708
+ if (in_compat_syscall()) {
709
+ struct compat_group_source_req gr32;
710
+
711
+ if (optlen != sizeof(gr32))
712
+ return -EINVAL;
713
+ if (copy_from_sockptr(&gr32, optval, sizeof(gr32)))
714
+ return -EFAULT;
715
+ greqs->gsr_interface = gr32.gsr_interface;
716
+ greqs->gsr_group = gr32.gsr_group;
717
+ greqs->gsr_source = gr32.gsr_source;
718
+ } else {
719
+ if (optlen != sizeof(*greqs))
720
+ return -EINVAL;
721
+ if (copy_from_sockptr(greqs, optval, sizeof(*greqs)))
722
+ return -EFAULT;
723
+ }
724
+
725
+ return 0;
726
+}
727
+
728
+static int do_mcast_group_source(struct sock *sk, int optname,
729
+ sockptr_t optval, int optlen)
730
+{
731
+ struct group_source_req greqs;
732
+ struct ip_mreq_source mreqs;
733
+ struct sockaddr_in *psin;
734
+ int omode, add, err;
735
+
736
+ err = copy_group_source_from_sockptr(&greqs, optval, optlen);
737
+ if (err)
738
+ return err;
739
+
740
+ if (greqs.gsr_group.ss_family != AF_INET ||
741
+ greqs.gsr_source.ss_family != AF_INET)
742
+ return -EADDRNOTAVAIL;
743
+
744
+ psin = (struct sockaddr_in *)&greqs.gsr_group;
745
+ mreqs.imr_multiaddr = psin->sin_addr.s_addr;
746
+ psin = (struct sockaddr_in *)&greqs.gsr_source;
747
+ mreqs.imr_sourceaddr = psin->sin_addr.s_addr;
748
+ mreqs.imr_interface = 0; /* use index for mc_source */
749
+
750
+ if (optname == MCAST_BLOCK_SOURCE) {
751
+ omode = MCAST_EXCLUDE;
752
+ add = 1;
753
+ } else if (optname == MCAST_UNBLOCK_SOURCE) {
754
+ omode = MCAST_EXCLUDE;
755
+ add = 0;
756
+ } else if (optname == MCAST_JOIN_SOURCE_GROUP) {
757
+ struct ip_mreqn mreq;
758
+
759
+ psin = (struct sockaddr_in *)&greqs.gsr_group;
760
+ mreq.imr_multiaddr = psin->sin_addr;
761
+ mreq.imr_address.s_addr = 0;
762
+ mreq.imr_ifindex = greqs.gsr_interface;
763
+ err = ip_mc_join_group_ssm(sk, &mreq, MCAST_INCLUDE);
764
+ if (err && err != -EADDRINUSE)
765
+ return err;
766
+ greqs.gsr_interface = mreq.imr_ifindex;
767
+ omode = MCAST_INCLUDE;
768
+ add = 1;
769
+ } else /* MCAST_LEAVE_SOURCE_GROUP */ {
770
+ omode = MCAST_INCLUDE;
771
+ add = 0;
772
+ }
773
+ return ip_mc_source(add, omode, sk, &mreqs, greqs.gsr_interface);
774
+}
775
+
776
+static int ip_set_mcast_msfilter(struct sock *sk, sockptr_t optval, int optlen)
777
+{
778
+ struct group_filter *gsf = NULL;
779
+ int err;
780
+
781
+ if (optlen < GROUP_FILTER_SIZE(0))
782
+ return -EINVAL;
783
+ if (optlen > READ_ONCE(sysctl_optmem_max))
784
+ return -ENOBUFS;
785
+
786
+ gsf = memdup_sockptr(optval, optlen);
787
+ if (IS_ERR(gsf))
788
+ return PTR_ERR(gsf);
789
+
790
+ /* numsrc >= (4G-140)/128 overflow in 32 bits */
791
+ err = -ENOBUFS;
792
+ if (gsf->gf_numsrc >= 0x1ffffff ||
793
+ gsf->gf_numsrc > READ_ONCE(sock_net(sk)->ipv4.sysctl_igmp_max_msf))
794
+ goto out_free_gsf;
795
+
796
+ err = -EINVAL;
797
+ if (GROUP_FILTER_SIZE(gsf->gf_numsrc) > optlen)
798
+ goto out_free_gsf;
799
+
800
+ err = set_mcast_msfilter(sk, gsf->gf_interface, gsf->gf_numsrc,
801
+ gsf->gf_fmode, &gsf->gf_group, gsf->gf_slist);
802
+out_free_gsf:
803
+ kfree(gsf);
804
+ return err;
805
+}
806
+
807
+static int compat_ip_set_mcast_msfilter(struct sock *sk, sockptr_t optval,
808
+ int optlen)
809
+{
810
+ const int size0 = offsetof(struct compat_group_filter, gf_slist);
811
+ struct compat_group_filter *gf32;
812
+ unsigned int n;
813
+ void *p;
814
+ int err;
815
+
816
+ if (optlen < size0)
817
+ return -EINVAL;
818
+ if (optlen > READ_ONCE(sysctl_optmem_max) - 4)
819
+ return -ENOBUFS;
820
+
821
+ p = kmalloc(optlen + 4, GFP_KERNEL);
822
+ if (!p)
823
+ return -ENOMEM;
824
+ gf32 = p + 4; /* we want ->gf_group and ->gf_slist aligned */
825
+
826
+ err = -EFAULT;
827
+ if (copy_from_sockptr(gf32, optval, optlen))
828
+ goto out_free_gsf;
829
+
830
+ /* numsrc >= (4G-140)/128 overflow in 32 bits */
831
+ n = gf32->gf_numsrc;
832
+ err = -ENOBUFS;
833
+ if (n >= 0x1ffffff)
834
+ goto out_free_gsf;
835
+
836
+ err = -EINVAL;
837
+ if (offsetof(struct compat_group_filter, gf_slist[n]) > optlen)
838
+ goto out_free_gsf;
839
+
840
+ /* numsrc >= (4G-140)/128 overflow in 32 bits */
841
+ err = -ENOBUFS;
842
+ if (n > READ_ONCE(sock_net(sk)->ipv4.sysctl_igmp_max_msf))
843
+ goto out_free_gsf;
844
+ err = set_mcast_msfilter(sk, gf32->gf_interface, n, gf32->gf_fmode,
845
+ &gf32->gf_group, gf32->gf_slist);
846
+out_free_gsf:
847
+ kfree(p);
848
+ return err;
849
+}
850
+
851
+static int ip_mcast_join_leave(struct sock *sk, int optname,
852
+ sockptr_t optval, int optlen)
853
+{
854
+ struct ip_mreqn mreq = { };
855
+ struct sockaddr_in *psin;
856
+ struct group_req greq;
857
+
858
+ if (optlen < sizeof(struct group_req))
859
+ return -EINVAL;
860
+ if (copy_from_sockptr(&greq, optval, sizeof(greq)))
861
+ return -EFAULT;
862
+
863
+ psin = (struct sockaddr_in *)&greq.gr_group;
864
+ if (psin->sin_family != AF_INET)
865
+ return -EINVAL;
866
+ mreq.imr_multiaddr = psin->sin_addr;
867
+ mreq.imr_ifindex = greq.gr_interface;
868
+ if (optname == MCAST_JOIN_GROUP)
869
+ return ip_mc_join_group(sk, &mreq);
870
+ return ip_mc_leave_group(sk, &mreq);
871
+}
872
+
873
+static int compat_ip_mcast_join_leave(struct sock *sk, int optname,
874
+ sockptr_t optval, int optlen)
875
+{
876
+ struct compat_group_req greq;
877
+ struct ip_mreqn mreq = { };
878
+ struct sockaddr_in *psin;
879
+
880
+ if (optlen < sizeof(struct compat_group_req))
881
+ return -EINVAL;
882
+ if (copy_from_sockptr(&greq, optval, sizeof(greq)))
883
+ return -EFAULT;
884
+
885
+ psin = (struct sockaddr_in *)&greq.gr_group;
886
+ if (psin->sin_family != AF_INET)
887
+ return -EINVAL;
888
+ mreq.imr_multiaddr = psin->sin_addr;
889
+ mreq.imr_ifindex = greq.gr_interface;
890
+
891
+ if (optname == MCAST_JOIN_GROUP)
892
+ return ip_mc_join_group(sk, &mreq);
893
+ return ip_mc_leave_group(sk, &mreq);
894
+}
895
+
896
+static int do_ip_setsockopt(struct sock *sk, int level, int optname,
897
+ sockptr_t optval, unsigned int optlen)
590898 {
591899 struct inet_sock *inet = inet_sk(sk);
592900 struct net *net = sock_net(sk);
....@@ -618,13 +926,14 @@
618926 case IP_RECVORIGDSTADDR:
619927 case IP_CHECKSUM:
620928 case IP_RECVFRAGSIZE:
929
+ case IP_RECVERR_RFC4884:
621930 if (optlen >= sizeof(int)) {
622
- if (get_user(val, (int __user *) optval))
931
+ if (copy_from_sockptr(&val, optval, sizeof(val)))
623932 return -EFAULT;
624933 } else if (optlen >= sizeof(char)) {
625934 unsigned char ucval;
626935
627
- if (get_user(ucval, (unsigned char __user *) optval))
936
+ if (copy_from_sockptr(&ucval, optval, sizeof(ucval)))
628937 return -EFAULT;
629938 val = (int) ucval;
630939 }
....@@ -649,8 +958,7 @@
649958
650959 if (optlen > 40)
651960 goto e_inval;
652
- err = ip_options_get_from_user(sock_net(sk), &opt,
653
- optval, optlen);
961
+ err = ip_options_get(sock_net(sk), &opt, optval, optlen);
654962 if (err)
655963 break;
656964 old = rcu_dereference_protected(inet->inet_opt,
....@@ -741,15 +1049,7 @@
7411049 inet->cmsg_flags &= ~IP_CMSG_RECVFRAGSIZE;
7421050 break;
7431051 case IP_TOS: /* This sets both TOS and Precedence */
744
- if (sk->sk_type == SOCK_STREAM) {
745
- val &= ~INET_ECN_MASK;
746
- val |= inet->tos & INET_ECN_MASK;
747
- }
748
- if (inet->tos != val) {
749
- inet->tos = val;
750
- sk->sk_priority = rt_tos2priority(val);
751
- sk_dst_reset(sk);
752
- }
1052
+ __ip_sock_set_tos(sk, val);
7531053 break;
7541054 case IP_TTL:
7551055 if (optlen < 1)
....@@ -784,6 +1084,11 @@
7841084 inet->recverr = !!val;
7851085 if (!val)
7861086 skb_queue_purge(&sk->sk_error_queue);
1087
+ break;
1088
+ case IP_RECVERR_RFC4884:
1089
+ if (val < 0 || val > 1)
1090
+ goto e_inval;
1091
+ inet->recverr_rfc4884 = !!val;
7871092 break;
7881093 case IP_MULTICAST_TTL:
7891094 if (sk->sk_type == SOCK_STREAM)
....@@ -826,8 +1131,7 @@
8261131 dev_put(dev);
8271132
8281133 err = -EINVAL;
829
- if (sk->sk_bound_dev_if &&
830
- (!midx || midx != sk->sk_bound_dev_if))
1134
+ if (sk->sk_bound_dev_if && midx != sk->sk_bound_dev_if)
8311135 break;
8321136
8331137 inet->uc_index = ifindex;
....@@ -851,17 +1155,17 @@
8511155
8521156 err = -EFAULT;
8531157 if (optlen >= sizeof(struct ip_mreqn)) {
854
- if (copy_from_user(&mreq, optval, sizeof(mreq)))
1158
+ if (copy_from_sockptr(&mreq, optval, sizeof(mreq)))
8551159 break;
8561160 } else {
8571161 memset(&mreq, 0, sizeof(mreq));
8581162 if (optlen >= sizeof(struct ip_mreq)) {
859
- if (copy_from_user(&mreq, optval,
860
- sizeof(struct ip_mreq)))
1163
+ if (copy_from_sockptr(&mreq, optval,
1164
+ sizeof(struct ip_mreq)))
8611165 break;
8621166 } else if (optlen >= sizeof(struct in_addr)) {
863
- if (copy_from_user(&mreq.imr_address, optval,
864
- sizeof(struct in_addr)))
1167
+ if (copy_from_sockptr(&mreq.imr_address, optval,
1168
+ sizeof(struct in_addr)))
8651169 break;
8661170 }
8671171 }
....@@ -891,7 +1195,7 @@
8911195 err = -EINVAL;
8921196 if (sk->sk_bound_dev_if &&
8931197 mreq.imr_ifindex != sk->sk_bound_dev_if &&
894
- (!midx || midx != sk->sk_bound_dev_if))
1198
+ midx != sk->sk_bound_dev_if)
8951199 break;
8961200
8971201 inet->mc_index = mreq.imr_ifindex;
....@@ -913,11 +1217,12 @@
9131217 goto e_inval;
9141218 err = -EFAULT;
9151219 if (optlen >= sizeof(struct ip_mreqn)) {
916
- if (copy_from_user(&mreq, optval, sizeof(mreq)))
1220
+ if (copy_from_sockptr(&mreq, optval, sizeof(mreq)))
9171221 break;
9181222 } else {
9191223 memset(&mreq, 0, sizeof(mreq));
920
- if (copy_from_user(&mreq, optval, sizeof(struct ip_mreq)))
1224
+ if (copy_from_sockptr(&mreq, optval,
1225
+ sizeof(struct ip_mreq)))
9211226 break;
9221227 }
9231228
....@@ -933,18 +1238,18 @@
9331238
9341239 if (optlen < IP_MSFILTER_SIZE(0))
9351240 goto e_inval;
936
- if (optlen > sysctl_optmem_max) {
1241
+ if (optlen > READ_ONCE(sysctl_optmem_max)) {
9371242 err = -ENOBUFS;
9381243 break;
9391244 }
940
- msf = memdup_user(optval, optlen);
1245
+ msf = memdup_sockptr(optval, optlen);
9411246 if (IS_ERR(msf)) {
9421247 err = PTR_ERR(msf);
9431248 break;
9441249 }
9451250 /* numsrc >= (1G-4) overflow in 32 bits */
9461251 if (msf->imsf_numsrc >= 0x3ffffffcU ||
947
- msf->imsf_numsrc > net->ipv4.sysctl_igmp_max_msf) {
1252
+ msf->imsf_numsrc > READ_ONCE(net->ipv4.sysctl_igmp_max_msf)) {
9481253 kfree(msf);
9491254 err = -ENOBUFS;
9501255 break;
....@@ -968,7 +1273,7 @@
9681273
9691274 if (optlen != sizeof(struct ip_mreq_source))
9701275 goto e_inval;
971
- if (copy_from_user(&mreqs, optval, sizeof(mreqs))) {
1276
+ if (copy_from_sockptr(&mreqs, optval, sizeof(mreqs))) {
9721277 err = -EFAULT;
9731278 break;
9741279 }
....@@ -998,145 +1303,24 @@
9981303 }
9991304 case MCAST_JOIN_GROUP:
10001305 case MCAST_LEAVE_GROUP:
1001
- {
1002
- struct group_req greq;
1003
- struct sockaddr_in *psin;
1004
- struct ip_mreqn mreq;
1005
-
1006
- if (optlen < sizeof(struct group_req))
1007
- goto e_inval;
1008
- err = -EFAULT;
1009
- if (copy_from_user(&greq, optval, sizeof(greq)))
1010
- break;
1011
- psin = (struct sockaddr_in *)&greq.gr_group;
1012
- if (psin->sin_family != AF_INET)
1013
- goto e_inval;
1014
- memset(&mreq, 0, sizeof(mreq));
1015
- mreq.imr_multiaddr = psin->sin_addr;
1016
- mreq.imr_ifindex = greq.gr_interface;
1017
-
1018
- if (optname == MCAST_JOIN_GROUP)
1019
- err = ip_mc_join_group(sk, &mreq);
1306
+ if (in_compat_syscall())
1307
+ err = compat_ip_mcast_join_leave(sk, optname, optval,
1308
+ optlen);
10201309 else
1021
- err = ip_mc_leave_group(sk, &mreq);
1310
+ err = ip_mcast_join_leave(sk, optname, optval, optlen);
10221311 break;
1023
- }
10241312 case MCAST_JOIN_SOURCE_GROUP:
10251313 case MCAST_LEAVE_SOURCE_GROUP:
10261314 case MCAST_BLOCK_SOURCE:
10271315 case MCAST_UNBLOCK_SOURCE:
1028
- {
1029
- struct group_source_req greqs;
1030
- struct ip_mreq_source mreqs;
1031
- struct sockaddr_in *psin;
1032
- int omode, add;
1033
-
1034
- if (optlen != sizeof(struct group_source_req))
1035
- goto e_inval;
1036
- if (copy_from_user(&greqs, optval, sizeof(greqs))) {
1037
- err = -EFAULT;
1038
- break;
1039
- }
1040
- if (greqs.gsr_group.ss_family != AF_INET ||
1041
- greqs.gsr_source.ss_family != AF_INET) {
1042
- err = -EADDRNOTAVAIL;
1043
- break;
1044
- }
1045
- psin = (struct sockaddr_in *)&greqs.gsr_group;
1046
- mreqs.imr_multiaddr = psin->sin_addr.s_addr;
1047
- psin = (struct sockaddr_in *)&greqs.gsr_source;
1048
- mreqs.imr_sourceaddr = psin->sin_addr.s_addr;
1049
- mreqs.imr_interface = 0; /* use index for mc_source */
1050
-
1051
- if (optname == MCAST_BLOCK_SOURCE) {
1052
- omode = MCAST_EXCLUDE;
1053
- add = 1;
1054
- } else if (optname == MCAST_UNBLOCK_SOURCE) {
1055
- omode = MCAST_EXCLUDE;
1056
- add = 0;
1057
- } else if (optname == MCAST_JOIN_SOURCE_GROUP) {
1058
- struct ip_mreqn mreq;
1059
-
1060
- psin = (struct sockaddr_in *)&greqs.gsr_group;
1061
- mreq.imr_multiaddr = psin->sin_addr;
1062
- mreq.imr_address.s_addr = 0;
1063
- mreq.imr_ifindex = greqs.gsr_interface;
1064
- err = ip_mc_join_group_ssm(sk, &mreq, MCAST_INCLUDE);
1065
- if (err && err != -EADDRINUSE)
1066
- break;
1067
- greqs.gsr_interface = mreq.imr_ifindex;
1068
- omode = MCAST_INCLUDE;
1069
- add = 1;
1070
- } else /* MCAST_LEAVE_SOURCE_GROUP */ {
1071
- omode = MCAST_INCLUDE;
1072
- add = 0;
1073
- }
1074
- err = ip_mc_source(add, omode, sk, &mreqs,
1075
- greqs.gsr_interface);
1316
+ err = do_mcast_group_source(sk, optname, optval, optlen);
10761317 break;
1077
- }
10781318 case MCAST_MSFILTER:
1079
- {
1080
- struct sockaddr_in *psin;
1081
- struct ip_msfilter *msf = NULL;
1082
- struct group_filter *gsf = NULL;
1083
- int msize, i, ifindex;
1084
-
1085
- if (optlen < GROUP_FILTER_SIZE(0))
1086
- goto e_inval;
1087
- if (optlen > sysctl_optmem_max) {
1088
- err = -ENOBUFS;
1089
- break;
1090
- }
1091
- gsf = memdup_user(optval, optlen);
1092
- if (IS_ERR(gsf)) {
1093
- err = PTR_ERR(gsf);
1094
- break;
1095
- }
1096
-
1097
- /* numsrc >= (4G-140)/128 overflow in 32 bits */
1098
- if (gsf->gf_numsrc >= 0x1ffffff ||
1099
- gsf->gf_numsrc > net->ipv4.sysctl_igmp_max_msf) {
1100
- err = -ENOBUFS;
1101
- goto mc_msf_out;
1102
- }
1103
- if (GROUP_FILTER_SIZE(gsf->gf_numsrc) > optlen) {
1104
- err = -EINVAL;
1105
- goto mc_msf_out;
1106
- }
1107
- msize = IP_MSFILTER_SIZE(gsf->gf_numsrc);
1108
- msf = kmalloc(msize, GFP_KERNEL);
1109
- if (!msf) {
1110
- err = -ENOBUFS;
1111
- goto mc_msf_out;
1112
- }
1113
- ifindex = gsf->gf_interface;
1114
- psin = (struct sockaddr_in *)&gsf->gf_group;
1115
- if (psin->sin_family != AF_INET) {
1116
- err = -EADDRNOTAVAIL;
1117
- goto mc_msf_out;
1118
- }
1119
- msf->imsf_multiaddr = psin->sin_addr.s_addr;
1120
- msf->imsf_interface = 0;
1121
- msf->imsf_fmode = gsf->gf_fmode;
1122
- msf->imsf_numsrc = gsf->gf_numsrc;
1123
- err = -EADDRNOTAVAIL;
1124
- for (i = 0; i < gsf->gf_numsrc; ++i) {
1125
- psin = (struct sockaddr_in *)&gsf->gf_slist[i];
1126
-
1127
- if (psin->sin_family != AF_INET)
1128
- goto mc_msf_out;
1129
- msf->imsf_slist[i] = psin->sin_addr.s_addr;
1130
- }
1131
- kfree(gsf);
1132
- gsf = NULL;
1133
-
1134
- err = ip_mc_msfilter(sk, msf, ifindex);
1135
-mc_msf_out:
1136
- kfree(msf);
1137
- kfree(gsf);
1319
+ if (in_compat_syscall())
1320
+ err = compat_ip_set_mcast_msfilter(sk, optval, optlen);
1321
+ else
1322
+ err = ip_set_mcast_msfilter(sk, optval, optlen);
11381323 break;
1139
- }
11401324 case IP_MULTICAST_ALL:
11411325 if (optlen < 1)
11421326 goto e_inval;
....@@ -1235,8 +1419,8 @@
12351419 skb_dst_drop(skb);
12361420 }
12371421
1238
-int ip_setsockopt(struct sock *sk, int level,
1239
- int optname, char __user *optval, unsigned int optlen)
1422
+int ip_setsockopt(struct sock *sk, int level, int optname, sockptr_t optval,
1423
+ unsigned int optlen)
12401424 {
12411425 int err;
12421426
....@@ -1261,34 +1445,6 @@
12611445 }
12621446 EXPORT_SYMBOL(ip_setsockopt);
12631447
1264
-#ifdef CONFIG_COMPAT
1265
-int compat_ip_setsockopt(struct sock *sk, int level, int optname,
1266
- char __user *optval, unsigned int optlen)
1267
-{
1268
- int err;
1269
-
1270
- if (level != SOL_IP)
1271
- return -ENOPROTOOPT;
1272
-
1273
- if (optname >= MCAST_JOIN_GROUP && optname <= MCAST_MSFILTER)
1274
- return compat_mc_setsockopt(sk, level, optname, optval, optlen,
1275
- ip_setsockopt);
1276
-
1277
- err = do_ip_setsockopt(sk, level, optname, optval, optlen);
1278
-#ifdef CONFIG_NETFILTER
1279
- /* we need to exclude all possible ENOPROTOOPTs except default case */
1280
- if (err == -ENOPROTOOPT && optname != IP_HDRINCL &&
1281
- optname != IP_IPSEC_POLICY &&
1282
- optname != IP_XFRM_POLICY &&
1283
- !ip_mroute_opt(optname))
1284
- err = compat_nf_setsockopt(sk, PF_INET, optname, optval,
1285
- optlen);
1286
-#endif
1287
- return err;
1288
-}
1289
-EXPORT_SYMBOL(compat_ip_setsockopt);
1290
-#endif
1291
-
12921448 /*
12931449 * Get the options. Note for future reference. The GET of IP options gets
12941450 * the _received_ ones. The set sets the _sent_ ones.
....@@ -1304,8 +1460,67 @@
13041460 return false;
13051461 }
13061462
1463
+static int ip_get_mcast_msfilter(struct sock *sk, void __user *optval,
1464
+ int __user *optlen, int len)
1465
+{
1466
+ const int size0 = offsetof(struct group_filter, gf_slist);
1467
+ struct group_filter __user *p = optval;
1468
+ struct group_filter gsf;
1469
+ int num;
1470
+ int err;
1471
+
1472
+ if (len < size0)
1473
+ return -EINVAL;
1474
+ if (copy_from_user(&gsf, p, size0))
1475
+ return -EFAULT;
1476
+
1477
+ num = gsf.gf_numsrc;
1478
+ err = ip_mc_gsfget(sk, &gsf, p->gf_slist);
1479
+ if (err)
1480
+ return err;
1481
+ if (gsf.gf_numsrc < num)
1482
+ num = gsf.gf_numsrc;
1483
+ if (put_user(GROUP_FILTER_SIZE(num), optlen) ||
1484
+ copy_to_user(p, &gsf, size0))
1485
+ return -EFAULT;
1486
+ return 0;
1487
+}
1488
+
1489
+static int compat_ip_get_mcast_msfilter(struct sock *sk, void __user *optval,
1490
+ int __user *optlen, int len)
1491
+{
1492
+ const int size0 = offsetof(struct compat_group_filter, gf_slist);
1493
+ struct compat_group_filter __user *p = optval;
1494
+ struct compat_group_filter gf32;
1495
+ struct group_filter gf;
1496
+ int num;
1497
+ int err;
1498
+
1499
+ if (len < size0)
1500
+ return -EINVAL;
1501
+ if (copy_from_user(&gf32, p, size0))
1502
+ return -EFAULT;
1503
+
1504
+ gf.gf_interface = gf32.gf_interface;
1505
+ gf.gf_fmode = gf32.gf_fmode;
1506
+ num = gf.gf_numsrc = gf32.gf_numsrc;
1507
+ gf.gf_group = gf32.gf_group;
1508
+
1509
+ err = ip_mc_gsfget(sk, &gf, p->gf_slist);
1510
+ if (err)
1511
+ return err;
1512
+ if (gf.gf_numsrc < num)
1513
+ num = gf.gf_numsrc;
1514
+ len = GROUP_FILTER_SIZE(num) - (sizeof(gf) - sizeof(gf32));
1515
+ if (put_user(len, optlen) ||
1516
+ put_user(gf.gf_fmode, &p->gf_fmode) ||
1517
+ put_user(gf.gf_numsrc, &p->gf_numsrc))
1518
+ return -EFAULT;
1519
+ return 0;
1520
+}
1521
+
13071522 static int do_ip_getsockopt(struct sock *sk, int level, int optname,
1308
- char __user *optval, int __user *optlen, unsigned int flags)
1523
+ char __user *optval, int __user *optlen)
13091524 {
13101525 struct inet_sock *inet = inet_sk(sk);
13111526 bool needs_rtnl = getsockopt_needs_rtnl(optname);
....@@ -1423,6 +1638,9 @@
14231638 case IP_RECVERR:
14241639 val = inet->recverr;
14251640 break;
1641
+ case IP_RECVERR_RFC4884:
1642
+ val = inet->recverr_rfc4884;
1643
+ break;
14261644 case IP_MULTICAST_TTL:
14271645 val = inet->mc_ttl;
14281646 break;
....@@ -1462,22 +1680,12 @@
14621680 goto out;
14631681 }
14641682 case MCAST_MSFILTER:
1465
- {
1466
- struct group_filter gsf;
1467
-
1468
- if (len < GROUP_FILTER_SIZE(0)) {
1469
- err = -EINVAL;
1470
- goto out;
1471
- }
1472
- if (copy_from_user(&gsf, optval, GROUP_FILTER_SIZE(0))) {
1473
- err = -EFAULT;
1474
- goto out;
1475
- }
1476
- err = ip_mc_gsfget(sk, &gsf,
1477
- (struct group_filter __user *)optval,
1478
- optlen);
1683
+ if (in_compat_syscall())
1684
+ err = compat_ip_get_mcast_msfilter(sk, optval, optlen,
1685
+ len);
1686
+ else
1687
+ err = ip_get_mcast_msfilter(sk, optval, optlen, len);
14791688 goto out;
1480
- }
14811689 case IP_MULTICAST_ALL:
14821690 val = inet->mc_all;
14831691 break;
....@@ -1490,9 +1698,10 @@
14901698 if (sk->sk_type != SOCK_STREAM)
14911699 return -ENOPROTOOPT;
14921700
1493
- msg.msg_control = (__force void *) optval;
1701
+ msg.msg_control_is_user = true;
1702
+ msg.msg_control_user = optval;
14941703 msg.msg_controllen = len;
1495
- msg.msg_flags = flags;
1704
+ msg.msg_flags = in_compat_syscall() ? MSG_CMSG_COMPAT : 0;
14961705
14971706 if (inet->cmsg_flags & IP_CMSG_PKTINFO) {
14981707 struct in_pktinfo info;
....@@ -1521,6 +1730,9 @@
15211730 break;
15221731 case IP_MINTTL:
15231732 val = inet->min_ttl;
1733
+ break;
1734
+ case IP_PROTOCOL:
1735
+ val = inet_sk(sk)->inet_num;
15241736 break;
15251737 default:
15261738 release_sock(sk);
....@@ -1556,7 +1768,8 @@
15561768 {
15571769 int err;
15581770
1559
- err = do_ip_getsockopt(sk, level, optname, optval, optlen, 0);
1771
+ err = do_ip_getsockopt(sk, level, optname, optval, optlen);
1772
+
15601773 #if IS_ENABLED(CONFIG_BPFILTER_UMH)
15611774 if (optname >= BPFILTER_IPT_SO_GET_INFO &&
15621775 optname < BPFILTER_IPT_GET_MAX)
....@@ -1580,41 +1793,3 @@
15801793 return err;
15811794 }
15821795 EXPORT_SYMBOL(ip_getsockopt);
1583
-
1584
-#ifdef CONFIG_COMPAT
1585
-int compat_ip_getsockopt(struct sock *sk, int level, int optname,
1586
- char __user *optval, int __user *optlen)
1587
-{
1588
- int err;
1589
-
1590
- if (optname == MCAST_MSFILTER)
1591
- return compat_mc_getsockopt(sk, level, optname, optval, optlen,
1592
- ip_getsockopt);
1593
-
1594
- err = do_ip_getsockopt(sk, level, optname, optval, optlen,
1595
- MSG_CMSG_COMPAT);
1596
-
1597
-#if IS_ENABLED(CONFIG_BPFILTER_UMH)
1598
- if (optname >= BPFILTER_IPT_SO_GET_INFO &&
1599
- optname < BPFILTER_IPT_GET_MAX)
1600
- err = bpfilter_ip_get_sockopt(sk, optname, optval, optlen);
1601
-#endif
1602
-#ifdef CONFIG_NETFILTER
1603
- /* we need to exclude all possible ENOPROTOOPTs except default case */
1604
- if (err == -ENOPROTOOPT && optname != IP_PKTOPTIONS &&
1605
- !ip_mroute_opt(optname)) {
1606
- int len;
1607
-
1608
- if (get_user(len, optlen))
1609
- return -EFAULT;
1610
-
1611
- err = compat_nf_getsockopt(sk, PF_INET, optname, optval, &len);
1612
- if (err >= 0)
1613
- err = put_user(len, optlen);
1614
- return err;
1615
- }
1616
-#endif
1617
- return err;
1618
-}
1619
-EXPORT_SYMBOL(compat_ip_getsockopt);
1620
-#endif