hc
2024-10-22 8ac6c7a54ed1b98d142dce24b11c6de6a1e239a5
kernel/net/appletalk/ddp.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * DDP: An implementation of the AppleTalk DDP protocol for
34 * Ethernet 'ELAP'.
....@@ -43,12 +44,6 @@
4344 * shared skb support 8)
4445 * Arnaldo C. de Melo : Move proc stuff to atalk_proc.c,
4546 * use seq_file
46
- *
47
- * This program is free software; you can redistribute it and/or
48
- * modify it under the terms of the GNU General Public License
49
- * as published by the Free Software Foundation; either version
50
- * 2 of the License, or (at your option) any later version.
51
- *
5247 */
5348
5449 #include <linux/capability.h>
....@@ -62,6 +57,7 @@
6257 #include <net/sock.h>
6358 #include <net/tcp_states.h>
6459 #include <net/route.h>
60
+#include <net/compat.h>
6561 #include <linux/atalk.h>
6662 #include <linux/highmem.h>
6763
....@@ -872,6 +868,24 @@
872868 return copy_to_user(arg, &atreq, sizeof(atreq)) ? -EFAULT : 0;
873869 }
874870
871
+static int atrtr_ioctl_addrt(struct rtentry *rt)
872
+{
873
+ struct net_device *dev = NULL;
874
+
875
+ if (rt->rt_dev) {
876
+ char name[IFNAMSIZ];
877
+
878
+ if (copy_from_user(name, rt->rt_dev, IFNAMSIZ-1))
879
+ return -EFAULT;
880
+ name[IFNAMSIZ-1] = '\0';
881
+
882
+ dev = __dev_get_by_name(&init_net, name);
883
+ if (!dev)
884
+ return -ENODEV;
885
+ }
886
+ return atrtr_create(rt, dev);
887
+}
888
+
875889 /* Routing ioctl() calls */
876890 static int atrtr_ioctl(unsigned int cmd, void __user *arg)
877891 {
....@@ -887,19 +901,8 @@
887901 return atrtr_delete(&((struct sockaddr_at *)
888902 &rt.rt_dst)->sat_addr);
889903
890
- case SIOCADDRT: {
891
- struct net_device *dev = NULL;
892
- if (rt.rt_dev) {
893
- char name[IFNAMSIZ];
894
- if (copy_from_user(name, rt.rt_dev, IFNAMSIZ-1))
895
- return -EFAULT;
896
- name[IFNAMSIZ-1] = '\0';
897
- dev = __dev_get_by_name(&init_net, name);
898
- if (!dev)
899
- return -ENODEV;
900
- }
901
- return atrtr_create(&rt, dev);
902
- }
904
+ case SIOCADDRT:
905
+ return atrtr_ioctl_addrt(&rt);
903906 }
904907 return -EINVAL;
905908 }
....@@ -958,8 +961,8 @@
958961 if (copy > len)
959962 copy = len;
960963 vaddr = kmap_atomic(skb_frag_page(frag));
961
- sum = atalk_sum_partial(vaddr + frag->page_offset +
962
- offset - start, copy, sum);
964
+ sum = atalk_sum_partial(vaddr + skb_frag_off(frag) +
965
+ offset - start, copy, sum);
963966 kunmap_atomic(vaddr);
964967
965968 if (!(len -= copy))
....@@ -1820,12 +1823,6 @@
18201823 rc = put_user(amount, (int __user *)argp);
18211824 break;
18221825 }
1823
- case SIOCGSTAMP:
1824
- rc = sock_get_timestamp(sk, argp);
1825
- break;
1826
- case SIOCGSTAMPNS:
1827
- rc = sock_get_timestampns(sk, argp);
1828
- break;
18291826 /* Routing */
18301827 case SIOCADDRT:
18311828 case SIOCDELRT:
....@@ -1852,20 +1849,58 @@
18521849
18531850
18541851 #ifdef CONFIG_COMPAT
1852
+static int atalk_compat_routing_ioctl(struct sock *sk, unsigned int cmd,
1853
+ struct compat_rtentry __user *ur)
1854
+{
1855
+ compat_uptr_t rtdev;
1856
+ struct rtentry rt;
1857
+
1858
+ if (copy_from_user(&rt.rt_dst, &ur->rt_dst,
1859
+ 3 * sizeof(struct sockaddr)) ||
1860
+ get_user(rt.rt_flags, &ur->rt_flags) ||
1861
+ get_user(rt.rt_metric, &ur->rt_metric) ||
1862
+ get_user(rt.rt_mtu, &ur->rt_mtu) ||
1863
+ get_user(rt.rt_window, &ur->rt_window) ||
1864
+ get_user(rt.rt_irtt, &ur->rt_irtt) ||
1865
+ get_user(rtdev, &ur->rt_dev))
1866
+ return -EFAULT;
1867
+
1868
+ switch (cmd) {
1869
+ case SIOCDELRT:
1870
+ if (rt.rt_dst.sa_family != AF_APPLETALK)
1871
+ return -EINVAL;
1872
+ return atrtr_delete(&((struct sockaddr_at *)
1873
+ &rt.rt_dst)->sat_addr);
1874
+
1875
+ case SIOCADDRT:
1876
+ rt.rt_dev = compat_ptr(rtdev);
1877
+ return atrtr_ioctl_addrt(&rt);
1878
+ default:
1879
+ return -EINVAL;
1880
+ }
1881
+}
18551882 static int atalk_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
18561883 {
1884
+ void __user *argp = compat_ptr(arg);
1885
+ struct sock *sk = sock->sk;
1886
+
1887
+ switch (cmd) {
1888
+ case SIOCADDRT:
1889
+ case SIOCDELRT:
1890
+ return atalk_compat_routing_ioctl(sk, cmd, argp);
18571891 /*
18581892 * SIOCATALKDIFADDR is a SIOCPROTOPRIVATE ioctl number, so we
18591893 * cannot handle it in common code. The data we access if ifreq
18601894 * here is compatible, so we can simply call the native
18611895 * handler.
18621896 */
1863
- if (cmd == SIOCATALKDIFADDR)
1864
- return atalk_ioctl(sock, cmd, (unsigned long)compat_ptr(arg));
1865
-
1866
- return -ENOIOCTLCMD;
1897
+ case SIOCATALKDIFADDR:
1898
+ return atalk_ioctl(sock, cmd, (unsigned long)argp);
1899
+ default:
1900
+ return -ENOIOCTLCMD;
1901
+ }
18671902 }
1868
-#endif
1903
+#endif /* CONFIG_COMPAT */
18691904
18701905
18711906 static const struct net_proto_family atalk_family_ops = {
....@@ -1885,13 +1920,12 @@
18851920 .getname = atalk_getname,
18861921 .poll = datagram_poll,
18871922 .ioctl = atalk_ioctl,
1923
+ .gettstamp = sock_gettstamp,
18881924 #ifdef CONFIG_COMPAT
18891925 .compat_ioctl = atalk_compat_ioctl,
18901926 #endif
18911927 .listen = sock_no_listen,
18921928 .shutdown = sock_no_shutdown,
1893
- .setsockopt = sock_no_setsockopt,
1894
- .getsockopt = sock_no_getsockopt,
18951929 .sendmsg = atalk_sendmsg,
18961930 .recvmsg = atalk_recvmsg,
18971931 .mmap = sock_no_mmap,