hc
2024-05-10 37f49e37ab4cb5d0bc4c60eb5c6d4dd57db767bb
kernel/net/ieee802154/socket.c
....@@ -1,16 +1,8 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * IEEE802154.4 socket interface
34 *
45 * Copyright 2007, 2008 Siemens AG
5
- *
6
- * This program is free software; you can redistribute it and/or modify
7
- * it under the terms of the GNU General Public License version 2
8
- * as published by the Free Software Foundation.
9
- *
10
- * This program is distributed in the hope that it will be useful,
11
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
- * GNU General Public License for more details.
146 *
157 * Written by:
168 * Sergey Lapin <slapin@ossfans.org>
....@@ -164,10 +156,6 @@
164156 struct sock *sk = sock->sk;
165157
166158 switch (cmd) {
167
- case SIOCGSTAMP:
168
- return sock_get_timestamp(sk, (struct timeval __user *)arg);
169
- case SIOCGSTAMPNS:
170
- return sock_get_timestampns(sk, (struct timespec __user *)arg);
171159 case SIOCGIFADDR:
172160 case SIOCSIFADDR:
173161 return ieee802154_dev_ioctl(sk, (struct ifreq __user *)arg,
....@@ -213,8 +201,9 @@
213201 int err = 0;
214202 struct net_device *dev = NULL;
215203
216
- if (len < sizeof(*uaddr))
217
- return -EINVAL;
204
+ err = ieee802154_sockaddr_check_size(uaddr, len);
205
+ if (err < 0)
206
+ return err;
218207
219208 uaddr = (struct sockaddr_ieee802154 *)_uaddr;
220209 if (uaddr->family != AF_IEEE802154)
....@@ -282,6 +271,10 @@
282271 if (size > mtu) {
283272 pr_debug("size = %zu, mtu = %u\n", size, mtu);
284273 err = -EMSGSIZE;
274
+ goto out_dev;
275
+ }
276
+ if (!size) {
277
+ err = 0;
285278 goto out_dev;
286279 }
287280
....@@ -394,7 +387,7 @@
394387 }
395388
396389 static int raw_setsockopt(struct sock *sk, int level, int optname,
397
- char __user *optval, unsigned int optlen)
390
+ sockptr_t optval, unsigned int optlen)
398391 {
399392 return -EOPNOTSUPP;
400393 }
....@@ -426,6 +419,7 @@
426419 .getname = sock_no_getname,
427420 .poll = datagram_poll,
428421 .ioctl = ieee802154_sock_ioctl,
422
+ .gettstamp = sock_gettstamp,
429423 .listen = sock_no_listen,
430424 .shutdown = sock_no_shutdown,
431425 .setsockopt = sock_common_setsockopt,
....@@ -434,10 +428,6 @@
434428 .recvmsg = sock_common_recvmsg,
435429 .mmap = sock_no_mmap,
436430 .sendpage = sock_no_sendpage,
437
-#ifdef CONFIG_COMPAT
438
- .compat_setsockopt = compat_sock_common_setsockopt,
439
- .compat_getsockopt = compat_sock_common_getsockopt,
440
-#endif
441431 };
442432
443433 /* DGRAM Sockets (802.15.4 dataframes) */
....@@ -509,11 +499,14 @@
509499
510500 ro->bound = 0;
511501
512
- if (len < sizeof(*addr))
502
+ err = ieee802154_sockaddr_check_size(addr, len);
503
+ if (err < 0)
513504 goto out;
514505
515
- if (addr->family != AF_IEEE802154)
506
+ if (addr->family != AF_IEEE802154) {
507
+ err = -EINVAL;
516508 goto out;
509
+ }
517510
518511 ieee802154_addr_from_sa(&haddr, &addr->addr);
519512 dev = ieee802154_get_dev(sock_net(sk), &haddr);
....@@ -580,8 +573,9 @@
580573 struct dgram_sock *ro = dgram_sk(sk);
581574 int err = 0;
582575
583
- if (len < sizeof(*addr))
584
- return -EINVAL;
576
+ err = ieee802154_sockaddr_check_size(addr, len);
577
+ if (err < 0)
578
+ return err;
585579
586580 if (addr->family != AF_IEEE802154)
587581 return -EINVAL;
....@@ -620,6 +614,7 @@
620614 struct ieee802154_mac_cb *cb;
621615 struct dgram_sock *ro = dgram_sk(sk);
622616 struct ieee802154_addr dst_addr;
617
+ DECLARE_SOCKADDR(struct sockaddr_ieee802154*, daddr, msg->msg_name);
623618 int hlen, tlen;
624619 int err;
625620
....@@ -628,10 +623,20 @@
628623 return -EOPNOTSUPP;
629624 }
630625
631
- if (!ro->connected && !msg->msg_name)
632
- return -EDESTADDRREQ;
633
- else if (ro->connected && msg->msg_name)
634
- return -EISCONN;
626
+ if (msg->msg_name) {
627
+ if (ro->connected)
628
+ return -EISCONN;
629
+ if (msg->msg_namelen < IEEE802154_MIN_NAMELEN)
630
+ return -EINVAL;
631
+ err = ieee802154_sockaddr_check_size(daddr, msg->msg_namelen);
632
+ if (err < 0)
633
+ return err;
634
+ ieee802154_addr_from_sa(&dst_addr, &daddr->addr);
635
+ } else {
636
+ if (!ro->connected)
637
+ return -EDESTADDRREQ;
638
+ dst_addr = ro->dst_addr;
639
+ }
635640
636641 if (!ro->bound)
637642 dev = dev_getfirstbyhwtype(sock_net(sk), ARPHRD_IEEE802154);
....@@ -667,16 +672,6 @@
667672 cb = mac_cb_init(skb);
668673 cb->type = IEEE802154_FC_TYPE_DATA;
669674 cb->ackreq = ro->want_ack;
670
-
671
- if (msg->msg_name) {
672
- DECLARE_SOCKADDR(struct sockaddr_ieee802154*,
673
- daddr, msg->msg_name);
674
-
675
- ieee802154_addr_from_sa(&dst_addr, &daddr->addr);
676
- } else {
677
- dst_addr = ro->dst_addr;
678
- }
679
-
680675 cb->secen = ro->secen;
681676 cb->secen_override = ro->secen_override;
682677 cb->seclevel = ro->seclevel;
....@@ -887,7 +882,7 @@
887882 }
888883
889884 static int dgram_setsockopt(struct sock *sk, int level, int optname,
890
- char __user *optval, unsigned int optlen)
885
+ sockptr_t optval, unsigned int optlen)
891886 {
892887 struct dgram_sock *ro = dgram_sk(sk);
893888 struct net *net = sock_net(sk);
....@@ -897,7 +892,7 @@
897892 if (optlen < sizeof(int))
898893 return -EINVAL;
899894
900
- if (get_user(val, (int __user *)optval))
895
+ if (copy_from_sockptr(&val, optval, sizeof(int)))
901896 return -EFAULT;
902897
903898 lock_sock(sk);
....@@ -988,6 +983,7 @@
988983 .getname = sock_no_getname,
989984 .poll = datagram_poll,
990985 .ioctl = ieee802154_sock_ioctl,
986
+ .gettstamp = sock_gettstamp,
991987 .listen = sock_no_listen,
992988 .shutdown = sock_no_shutdown,
993989 .setsockopt = sock_common_setsockopt,
....@@ -996,10 +992,6 @@
996992 .recvmsg = sock_common_recvmsg,
997993 .mmap = sock_no_mmap,
998994 .sendpage = sock_no_sendpage,
999
-#ifdef CONFIG_COMPAT
1000
- .compat_setsockopt = compat_sock_common_setsockopt,
1001
- .compat_getsockopt = compat_sock_common_getsockopt,
1002
-#endif
1003995 };
1004996
1005997 static void ieee802154_sock_destruct(struct sock *sk)
....@@ -1110,7 +1102,7 @@
11101102
11111103 static int __init af_ieee802154_init(void)
11121104 {
1113
- int rc = -EINVAL;
1105
+ int rc;
11141106
11151107 rc = proto_register(&ieee802154_raw_prot, 1);
11161108 if (rc)