forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-11 6778948f9de86c3cfaf36725a7c87dcff9ba247f
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;
....@@ -343,6 +344,8 @@
343344 return -EINVAL;
344345
345346 new_ra = on ? kmalloc(sizeof(*new_ra), GFP_KERNEL) : NULL;
347
+ if (on && !new_ra)
348
+ return -ENOMEM;
346349
347350 mutex_lock(&net->ipv4.ra_mutex);
348351 for (rap = &net->ipv4.ra_chain;
....@@ -387,6 +390,18 @@
387390 return 0;
388391 }
389392
393
+static void ipv4_icmp_error_rfc4884(const struct sk_buff *skb,
394
+ struct sock_ee_data_rfc4884 *out)
395
+{
396
+ switch (icmp_hdr(skb)->type) {
397
+ case ICMP_DEST_UNREACH:
398
+ case ICMP_TIME_EXCEEDED:
399
+ case ICMP_PARAMETERPROB:
400
+ ip_icmp_error_rfc4884(skb, out, sizeof(struct icmphdr),
401
+ icmp_hdr(skb)->un.reserved[1] * 4);
402
+ }
403
+}
404
+
390405 void ip_icmp_error(struct sock *sk, struct sk_buff *skb, int err,
391406 __be16 port, u32 info, u8 *payload)
392407 {
....@@ -409,6 +424,9 @@
409424 serr->port = port;
410425
411426 if (skb_pull(skb, payload - skb->data)) {
427
+ if (inet_sk(sk)->recverr_rfc4884)
428
+ ipv4_icmp_error_rfc4884(skb, &serr->ee.ee_rfc4884);
429
+
412430 skb_reset_transport_header(skb);
413431 if (sock_queue_err_skb(sk, skb) == 0)
414432 return;
....@@ -558,6 +576,61 @@
558576 return err;
559577 }
560578
579
+static void __ip_sock_set_tos(struct sock *sk, int val)
580
+{
581
+ if (sk->sk_type == SOCK_STREAM) {
582
+ val &= ~INET_ECN_MASK;
583
+ val |= inet_sk(sk)->tos & INET_ECN_MASK;
584
+ }
585
+ if (inet_sk(sk)->tos != val) {
586
+ inet_sk(sk)->tos = val;
587
+ sk->sk_priority = rt_tos2priority(val);
588
+ sk_dst_reset(sk);
589
+ }
590
+}
591
+
592
+void ip_sock_set_tos(struct sock *sk, int val)
593
+{
594
+ lock_sock(sk);
595
+ __ip_sock_set_tos(sk, val);
596
+ release_sock(sk);
597
+}
598
+EXPORT_SYMBOL(ip_sock_set_tos);
599
+
600
+void ip_sock_set_freebind(struct sock *sk)
601
+{
602
+ lock_sock(sk);
603
+ inet_sk(sk)->freebind = true;
604
+ release_sock(sk);
605
+}
606
+EXPORT_SYMBOL(ip_sock_set_freebind);
607
+
608
+void ip_sock_set_recverr(struct sock *sk)
609
+{
610
+ lock_sock(sk);
611
+ inet_sk(sk)->recverr = true;
612
+ release_sock(sk);
613
+}
614
+EXPORT_SYMBOL(ip_sock_set_recverr);
615
+
616
+int ip_sock_set_mtu_discover(struct sock *sk, int val)
617
+{
618
+ if (val < IP_PMTUDISC_DONT || val > IP_PMTUDISC_OMIT)
619
+ return -EINVAL;
620
+ lock_sock(sk);
621
+ inet_sk(sk)->pmtudisc = val;
622
+ release_sock(sk);
623
+ return 0;
624
+}
625
+EXPORT_SYMBOL(ip_sock_set_mtu_discover);
626
+
627
+void ip_sock_set_pktinfo(struct sock *sk)
628
+{
629
+ lock_sock(sk);
630
+ inet_sk(sk)->cmsg_flags |= IP_CMSG_PKTINFO;
631
+ release_sock(sk);
632
+}
633
+EXPORT_SYMBOL(ip_sock_set_pktinfo);
561634
562635 /*
563636 * Socket option code for IP. This is the end of the line after any
....@@ -585,8 +658,236 @@
585658 return false;
586659 }
587660
588
-static int do_ip_setsockopt(struct sock *sk, int level,
589
- int optname, char __user *optval, unsigned int optlen)
661
+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
+ int msize = IP_MSFILTER_SIZE(numsrc);
667
+ struct ip_msfilter *msf;
668
+ struct sockaddr_in *psin;
669
+ int err, i;
670
+
671
+ msf = kmalloc(msize, GFP_KERNEL);
672
+ if (!msf)
673
+ return -ENOBUFS;
674
+
675
+ psin = (struct sockaddr_in *)group;
676
+ if (psin->sin_family != AF_INET)
677
+ goto Eaddrnotavail;
678
+ msf->imsf_multiaddr = psin->sin_addr.s_addr;
679
+ msf->imsf_interface = 0;
680
+ msf->imsf_fmode = fmode;
681
+ msf->imsf_numsrc = numsrc;
682
+ for (i = 0; i < numsrc; ++i) {
683
+ psin = (struct sockaddr_in *)&list[i];
684
+
685
+ if (psin->sin_family != AF_INET)
686
+ goto Eaddrnotavail;
687
+ msf->imsf_slist[i] = psin->sin_addr.s_addr;
688
+ }
689
+ err = ip_mc_msfilter(sk, msf, ifindex);
690
+ kfree(msf);
691
+ return err;
692
+
693
+Eaddrnotavail:
694
+ kfree(msf);
695
+ return -EADDRNOTAVAIL;
696
+}
697
+
698
+static int copy_group_source_from_sockptr(struct group_source_req *greqs,
699
+ sockptr_t optval, int optlen)
700
+{
701
+ if (in_compat_syscall()) {
702
+ struct compat_group_source_req gr32;
703
+
704
+ if (optlen != sizeof(gr32))
705
+ return -EINVAL;
706
+ if (copy_from_sockptr(&gr32, optval, sizeof(gr32)))
707
+ return -EFAULT;
708
+ greqs->gsr_interface = gr32.gsr_interface;
709
+ greqs->gsr_group = gr32.gsr_group;
710
+ greqs->gsr_source = gr32.gsr_source;
711
+ } else {
712
+ if (optlen != sizeof(*greqs))
713
+ return -EINVAL;
714
+ if (copy_from_sockptr(greqs, optval, sizeof(*greqs)))
715
+ return -EFAULT;
716
+ }
717
+
718
+ return 0;
719
+}
720
+
721
+static int do_mcast_group_source(struct sock *sk, int optname,
722
+ sockptr_t optval, int optlen)
723
+{
724
+ struct group_source_req greqs;
725
+ struct ip_mreq_source mreqs;
726
+ struct sockaddr_in *psin;
727
+ int omode, add, err;
728
+
729
+ err = copy_group_source_from_sockptr(&greqs, optval, optlen);
730
+ if (err)
731
+ return err;
732
+
733
+ if (greqs.gsr_group.ss_family != AF_INET ||
734
+ greqs.gsr_source.ss_family != AF_INET)
735
+ return -EADDRNOTAVAIL;
736
+
737
+ psin = (struct sockaddr_in *)&greqs.gsr_group;
738
+ mreqs.imr_multiaddr = psin->sin_addr.s_addr;
739
+ psin = (struct sockaddr_in *)&greqs.gsr_source;
740
+ mreqs.imr_sourceaddr = psin->sin_addr.s_addr;
741
+ mreqs.imr_interface = 0; /* use index for mc_source */
742
+
743
+ if (optname == MCAST_BLOCK_SOURCE) {
744
+ omode = MCAST_EXCLUDE;
745
+ add = 1;
746
+ } else if (optname == MCAST_UNBLOCK_SOURCE) {
747
+ omode = MCAST_EXCLUDE;
748
+ add = 0;
749
+ } else if (optname == MCAST_JOIN_SOURCE_GROUP) {
750
+ struct ip_mreqn mreq;
751
+
752
+ psin = (struct sockaddr_in *)&greqs.gsr_group;
753
+ mreq.imr_multiaddr = psin->sin_addr;
754
+ mreq.imr_address.s_addr = 0;
755
+ mreq.imr_ifindex = greqs.gsr_interface;
756
+ err = ip_mc_join_group_ssm(sk, &mreq, MCAST_INCLUDE);
757
+ if (err && err != -EADDRINUSE)
758
+ return err;
759
+ greqs.gsr_interface = mreq.imr_ifindex;
760
+ omode = MCAST_INCLUDE;
761
+ add = 1;
762
+ } else /* MCAST_LEAVE_SOURCE_GROUP */ {
763
+ omode = MCAST_INCLUDE;
764
+ add = 0;
765
+ }
766
+ return ip_mc_source(add, omode, sk, &mreqs, greqs.gsr_interface);
767
+}
768
+
769
+static int ip_set_mcast_msfilter(struct sock *sk, sockptr_t optval, int optlen)
770
+{
771
+ struct group_filter *gsf = NULL;
772
+ int err;
773
+
774
+ if (optlen < GROUP_FILTER_SIZE(0))
775
+ return -EINVAL;
776
+ if (optlen > READ_ONCE(sysctl_optmem_max))
777
+ return -ENOBUFS;
778
+
779
+ gsf = memdup_sockptr(optval, optlen);
780
+ if (IS_ERR(gsf))
781
+ return PTR_ERR(gsf);
782
+
783
+ /* numsrc >= (4G-140)/128 overflow in 32 bits */
784
+ err = -ENOBUFS;
785
+ if (gsf->gf_numsrc >= 0x1ffffff ||
786
+ gsf->gf_numsrc > READ_ONCE(sock_net(sk)->ipv4.sysctl_igmp_max_msf))
787
+ goto out_free_gsf;
788
+
789
+ err = -EINVAL;
790
+ if (GROUP_FILTER_SIZE(gsf->gf_numsrc) > optlen)
791
+ goto out_free_gsf;
792
+
793
+ err = set_mcast_msfilter(sk, gsf->gf_interface, gsf->gf_numsrc,
794
+ gsf->gf_fmode, &gsf->gf_group, gsf->gf_slist);
795
+out_free_gsf:
796
+ kfree(gsf);
797
+ return err;
798
+}
799
+
800
+static int compat_ip_set_mcast_msfilter(struct sock *sk, sockptr_t optval,
801
+ int optlen)
802
+{
803
+ const int size0 = offsetof(struct compat_group_filter, gf_slist);
804
+ struct compat_group_filter *gf32;
805
+ unsigned int n;
806
+ void *p;
807
+ int err;
808
+
809
+ if (optlen < size0)
810
+ return -EINVAL;
811
+ if (optlen > READ_ONCE(sysctl_optmem_max) - 4)
812
+ return -ENOBUFS;
813
+
814
+ p = kmalloc(optlen + 4, GFP_KERNEL);
815
+ if (!p)
816
+ return -ENOMEM;
817
+ gf32 = p + 4; /* we want ->gf_group and ->gf_slist aligned */
818
+
819
+ err = -EFAULT;
820
+ if (copy_from_sockptr(gf32, optval, optlen))
821
+ goto out_free_gsf;
822
+
823
+ /* numsrc >= (4G-140)/128 overflow in 32 bits */
824
+ n = gf32->gf_numsrc;
825
+ err = -ENOBUFS;
826
+ if (n >= 0x1ffffff)
827
+ goto out_free_gsf;
828
+
829
+ err = -EINVAL;
830
+ if (offsetof(struct compat_group_filter, gf_slist[n]) > optlen)
831
+ goto out_free_gsf;
832
+
833
+ /* numsrc >= (4G-140)/128 overflow in 32 bits */
834
+ err = -ENOBUFS;
835
+ if (n > READ_ONCE(sock_net(sk)->ipv4.sysctl_igmp_max_msf))
836
+ goto out_free_gsf;
837
+ err = set_mcast_msfilter(sk, gf32->gf_interface, n, gf32->gf_fmode,
838
+ &gf32->gf_group, gf32->gf_slist);
839
+out_free_gsf:
840
+ kfree(p);
841
+ return err;
842
+}
843
+
844
+static int ip_mcast_join_leave(struct sock *sk, int optname,
845
+ sockptr_t optval, int optlen)
846
+{
847
+ struct ip_mreqn mreq = { };
848
+ struct sockaddr_in *psin;
849
+ struct group_req greq;
850
+
851
+ if (optlen < sizeof(struct group_req))
852
+ return -EINVAL;
853
+ if (copy_from_sockptr(&greq, optval, sizeof(greq)))
854
+ return -EFAULT;
855
+
856
+ psin = (struct sockaddr_in *)&greq.gr_group;
857
+ if (psin->sin_family != AF_INET)
858
+ return -EINVAL;
859
+ mreq.imr_multiaddr = psin->sin_addr;
860
+ mreq.imr_ifindex = greq.gr_interface;
861
+ if (optname == MCAST_JOIN_GROUP)
862
+ return ip_mc_join_group(sk, &mreq);
863
+ return ip_mc_leave_group(sk, &mreq);
864
+}
865
+
866
+static int compat_ip_mcast_join_leave(struct sock *sk, int optname,
867
+ sockptr_t optval, int optlen)
868
+{
869
+ struct compat_group_req greq;
870
+ struct ip_mreqn mreq = { };
871
+ struct sockaddr_in *psin;
872
+
873
+ if (optlen < sizeof(struct compat_group_req))
874
+ return -EINVAL;
875
+ if (copy_from_sockptr(&greq, optval, sizeof(greq)))
876
+ return -EFAULT;
877
+
878
+ psin = (struct sockaddr_in *)&greq.gr_group;
879
+ if (psin->sin_family != AF_INET)
880
+ return -EINVAL;
881
+ mreq.imr_multiaddr = psin->sin_addr;
882
+ mreq.imr_ifindex = greq.gr_interface;
883
+
884
+ if (optname == MCAST_JOIN_GROUP)
885
+ return ip_mc_join_group(sk, &mreq);
886
+ return ip_mc_leave_group(sk, &mreq);
887
+}
888
+
889
+static int do_ip_setsockopt(struct sock *sk, int level, int optname,
890
+ sockptr_t optval, unsigned int optlen)
590891 {
591892 struct inet_sock *inet = inet_sk(sk);
592893 struct net *net = sock_net(sk);
....@@ -618,13 +919,14 @@
618919 case IP_RECVORIGDSTADDR:
619920 case IP_CHECKSUM:
620921 case IP_RECVFRAGSIZE:
922
+ case IP_RECVERR_RFC4884:
621923 if (optlen >= sizeof(int)) {
622
- if (get_user(val, (int __user *) optval))
924
+ if (copy_from_sockptr(&val, optval, sizeof(val)))
623925 return -EFAULT;
624926 } else if (optlen >= sizeof(char)) {
625927 unsigned char ucval;
626928
627
- if (get_user(ucval, (unsigned char __user *) optval))
929
+ if (copy_from_sockptr(&ucval, optval, sizeof(ucval)))
628930 return -EFAULT;
629931 val = (int) ucval;
630932 }
....@@ -649,8 +951,7 @@
649951
650952 if (optlen > 40)
651953 goto e_inval;
652
- err = ip_options_get_from_user(sock_net(sk), &opt,
653
- optval, optlen);
954
+ err = ip_options_get(sock_net(sk), &opt, optval, optlen);
654955 if (err)
655956 break;
656957 old = rcu_dereference_protected(inet->inet_opt,
....@@ -741,15 +1042,7 @@
7411042 inet->cmsg_flags &= ~IP_CMSG_RECVFRAGSIZE;
7421043 break;
7431044 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
- }
1045
+ __ip_sock_set_tos(sk, val);
7531046 break;
7541047 case IP_TTL:
7551048 if (optlen < 1)
....@@ -784,6 +1077,11 @@
7841077 inet->recverr = !!val;
7851078 if (!val)
7861079 skb_queue_purge(&sk->sk_error_queue);
1080
+ break;
1081
+ case IP_RECVERR_RFC4884:
1082
+ if (val < 0 || val > 1)
1083
+ goto e_inval;
1084
+ inet->recverr_rfc4884 = !!val;
7871085 break;
7881086 case IP_MULTICAST_TTL:
7891087 if (sk->sk_type == SOCK_STREAM)
....@@ -826,8 +1124,7 @@
8261124 dev_put(dev);
8271125
8281126 err = -EINVAL;
829
- if (sk->sk_bound_dev_if &&
830
- (!midx || midx != sk->sk_bound_dev_if))
1127
+ if (sk->sk_bound_dev_if && midx != sk->sk_bound_dev_if)
8311128 break;
8321129
8331130 inet->uc_index = ifindex;
....@@ -851,17 +1148,17 @@
8511148
8521149 err = -EFAULT;
8531150 if (optlen >= sizeof(struct ip_mreqn)) {
854
- if (copy_from_user(&mreq, optval, sizeof(mreq)))
1151
+ if (copy_from_sockptr(&mreq, optval, sizeof(mreq)))
8551152 break;
8561153 } else {
8571154 memset(&mreq, 0, sizeof(mreq));
8581155 if (optlen >= sizeof(struct ip_mreq)) {
859
- if (copy_from_user(&mreq, optval,
860
- sizeof(struct ip_mreq)))
1156
+ if (copy_from_sockptr(&mreq, optval,
1157
+ sizeof(struct ip_mreq)))
8611158 break;
8621159 } else if (optlen >= sizeof(struct in_addr)) {
863
- if (copy_from_user(&mreq.imr_address, optval,
864
- sizeof(struct in_addr)))
1160
+ if (copy_from_sockptr(&mreq.imr_address, optval,
1161
+ sizeof(struct in_addr)))
8651162 break;
8661163 }
8671164 }
....@@ -891,7 +1188,7 @@
8911188 err = -EINVAL;
8921189 if (sk->sk_bound_dev_if &&
8931190 mreq.imr_ifindex != sk->sk_bound_dev_if &&
894
- (!midx || midx != sk->sk_bound_dev_if))
1191
+ midx != sk->sk_bound_dev_if)
8951192 break;
8961193
8971194 inet->mc_index = mreq.imr_ifindex;
....@@ -913,11 +1210,12 @@
9131210 goto e_inval;
9141211 err = -EFAULT;
9151212 if (optlen >= sizeof(struct ip_mreqn)) {
916
- if (copy_from_user(&mreq, optval, sizeof(mreq)))
1213
+ if (copy_from_sockptr(&mreq, optval, sizeof(mreq)))
9171214 break;
9181215 } else {
9191216 memset(&mreq, 0, sizeof(mreq));
920
- if (copy_from_user(&mreq, optval, sizeof(struct ip_mreq)))
1217
+ if (copy_from_sockptr(&mreq, optval,
1218
+ sizeof(struct ip_mreq)))
9211219 break;
9221220 }
9231221
....@@ -933,18 +1231,18 @@
9331231
9341232 if (optlen < IP_MSFILTER_SIZE(0))
9351233 goto e_inval;
936
- if (optlen > sysctl_optmem_max) {
1234
+ if (optlen > READ_ONCE(sysctl_optmem_max)) {
9371235 err = -ENOBUFS;
9381236 break;
9391237 }
940
- msf = memdup_user(optval, optlen);
1238
+ msf = memdup_sockptr(optval, optlen);
9411239 if (IS_ERR(msf)) {
9421240 err = PTR_ERR(msf);
9431241 break;
9441242 }
9451243 /* numsrc >= (1G-4) overflow in 32 bits */
9461244 if (msf->imsf_numsrc >= 0x3ffffffcU ||
947
- msf->imsf_numsrc > net->ipv4.sysctl_igmp_max_msf) {
1245
+ msf->imsf_numsrc > READ_ONCE(net->ipv4.sysctl_igmp_max_msf)) {
9481246 kfree(msf);
9491247 err = -ENOBUFS;
9501248 break;
....@@ -968,7 +1266,7 @@
9681266
9691267 if (optlen != sizeof(struct ip_mreq_source))
9701268 goto e_inval;
971
- if (copy_from_user(&mreqs, optval, sizeof(mreqs))) {
1269
+ if (copy_from_sockptr(&mreqs, optval, sizeof(mreqs))) {
9721270 err = -EFAULT;
9731271 break;
9741272 }
....@@ -998,145 +1296,24 @@
9981296 }
9991297 case MCAST_JOIN_GROUP:
10001298 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);
1299
+ if (in_compat_syscall())
1300
+ err = compat_ip_mcast_join_leave(sk, optname, optval,
1301
+ optlen);
10201302 else
1021
- err = ip_mc_leave_group(sk, &mreq);
1303
+ err = ip_mcast_join_leave(sk, optname, optval, optlen);
10221304 break;
1023
- }
10241305 case MCAST_JOIN_SOURCE_GROUP:
10251306 case MCAST_LEAVE_SOURCE_GROUP:
10261307 case MCAST_BLOCK_SOURCE:
10271308 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);
1309
+ err = do_mcast_group_source(sk, optname, optval, optlen);
10761310 break;
1077
- }
10781311 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);
1312
+ if (in_compat_syscall())
1313
+ err = compat_ip_set_mcast_msfilter(sk, optval, optlen);
1314
+ else
1315
+ err = ip_set_mcast_msfilter(sk, optval, optlen);
11381316 break;
1139
- }
11401317 case IP_MULTICAST_ALL:
11411318 if (optlen < 1)
11421319 goto e_inval;
....@@ -1235,8 +1412,8 @@
12351412 skb_dst_drop(skb);
12361413 }
12371414
1238
-int ip_setsockopt(struct sock *sk, int level,
1239
- int optname, char __user *optval, unsigned int optlen)
1415
+int ip_setsockopt(struct sock *sk, int level, int optname, sockptr_t optval,
1416
+ unsigned int optlen)
12401417 {
12411418 int err;
12421419
....@@ -1261,34 +1438,6 @@
12611438 }
12621439 EXPORT_SYMBOL(ip_setsockopt);
12631440
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
-
12921441 /*
12931442 * Get the options. Note for future reference. The GET of IP options gets
12941443 * the _received_ ones. The set sets the _sent_ ones.
....@@ -1304,8 +1453,67 @@
13041453 return false;
13051454 }
13061455
1456
+static int ip_get_mcast_msfilter(struct sock *sk, void __user *optval,
1457
+ int __user *optlen, int len)
1458
+{
1459
+ const int size0 = offsetof(struct group_filter, gf_slist);
1460
+ struct group_filter __user *p = optval;
1461
+ struct group_filter gsf;
1462
+ int num;
1463
+ int err;
1464
+
1465
+ if (len < size0)
1466
+ return -EINVAL;
1467
+ if (copy_from_user(&gsf, p, size0))
1468
+ return -EFAULT;
1469
+
1470
+ num = gsf.gf_numsrc;
1471
+ err = ip_mc_gsfget(sk, &gsf, p->gf_slist);
1472
+ if (err)
1473
+ return err;
1474
+ if (gsf.gf_numsrc < num)
1475
+ num = gsf.gf_numsrc;
1476
+ if (put_user(GROUP_FILTER_SIZE(num), optlen) ||
1477
+ copy_to_user(p, &gsf, size0))
1478
+ return -EFAULT;
1479
+ return 0;
1480
+}
1481
+
1482
+static int compat_ip_get_mcast_msfilter(struct sock *sk, void __user *optval,
1483
+ int __user *optlen, int len)
1484
+{
1485
+ const int size0 = offsetof(struct compat_group_filter, gf_slist);
1486
+ struct compat_group_filter __user *p = optval;
1487
+ struct compat_group_filter gf32;
1488
+ struct group_filter gf;
1489
+ int num;
1490
+ int err;
1491
+
1492
+ if (len < size0)
1493
+ return -EINVAL;
1494
+ if (copy_from_user(&gf32, p, size0))
1495
+ return -EFAULT;
1496
+
1497
+ gf.gf_interface = gf32.gf_interface;
1498
+ gf.gf_fmode = gf32.gf_fmode;
1499
+ num = gf.gf_numsrc = gf32.gf_numsrc;
1500
+ gf.gf_group = gf32.gf_group;
1501
+
1502
+ err = ip_mc_gsfget(sk, &gf, p->gf_slist);
1503
+ if (err)
1504
+ return err;
1505
+ if (gf.gf_numsrc < num)
1506
+ num = gf.gf_numsrc;
1507
+ len = GROUP_FILTER_SIZE(num) - (sizeof(gf) - sizeof(gf32));
1508
+ if (put_user(len, optlen) ||
1509
+ put_user(gf.gf_fmode, &p->gf_fmode) ||
1510
+ put_user(gf.gf_numsrc, &p->gf_numsrc))
1511
+ return -EFAULT;
1512
+ return 0;
1513
+}
1514
+
13071515 static int do_ip_getsockopt(struct sock *sk, int level, int optname,
1308
- char __user *optval, int __user *optlen, unsigned int flags)
1516
+ char __user *optval, int __user *optlen)
13091517 {
13101518 struct inet_sock *inet = inet_sk(sk);
13111519 bool needs_rtnl = getsockopt_needs_rtnl(optname);
....@@ -1423,6 +1631,9 @@
14231631 case IP_RECVERR:
14241632 val = inet->recverr;
14251633 break;
1634
+ case IP_RECVERR_RFC4884:
1635
+ val = inet->recverr_rfc4884;
1636
+ break;
14261637 case IP_MULTICAST_TTL:
14271638 val = inet->mc_ttl;
14281639 break;
....@@ -1462,22 +1673,12 @@
14621673 goto out;
14631674 }
14641675 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);
1676
+ if (in_compat_syscall())
1677
+ err = compat_ip_get_mcast_msfilter(sk, optval, optlen,
1678
+ len);
1679
+ else
1680
+ err = ip_get_mcast_msfilter(sk, optval, optlen, len);
14791681 goto out;
1480
- }
14811682 case IP_MULTICAST_ALL:
14821683 val = inet->mc_all;
14831684 break;
....@@ -1490,9 +1691,10 @@
14901691 if (sk->sk_type != SOCK_STREAM)
14911692 return -ENOPROTOOPT;
14921693
1493
- msg.msg_control = (__force void *) optval;
1694
+ msg.msg_control_is_user = true;
1695
+ msg.msg_control_user = optval;
14941696 msg.msg_controllen = len;
1495
- msg.msg_flags = flags;
1697
+ msg.msg_flags = in_compat_syscall() ? MSG_CMSG_COMPAT : 0;
14961698
14971699 if (inet->cmsg_flags & IP_CMSG_PKTINFO) {
14981700 struct in_pktinfo info;
....@@ -1556,7 +1758,8 @@
15561758 {
15571759 int err;
15581760
1559
- err = do_ip_getsockopt(sk, level, optname, optval, optlen, 0);
1761
+ err = do_ip_getsockopt(sk, level, optname, optval, optlen);
1762
+
15601763 #if IS_ENABLED(CONFIG_BPFILTER_UMH)
15611764 if (optname >= BPFILTER_IPT_SO_GET_INFO &&
15621765 optname < BPFILTER_IPT_GET_MAX)
....@@ -1580,41 +1783,3 @@
15801783 return err;
15811784 }
15821785 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