hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/net/can/bcm.c
....@@ -1,3 +1,4 @@
1
+// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
12 /*
23 * bcm.c - Broadcast Manager to filter/send (cyclic) CAN content
34 *
....@@ -80,12 +81,12 @@
8081 (CAN_EFF_MASK | CAN_EFF_FLAG | CAN_RTR_FLAG) : \
8182 (CAN_SFF_MASK | CAN_EFF_FLAG | CAN_RTR_FLAG))
8283
83
-#define CAN_BCM_VERSION "20170425"
84
-
8584 MODULE_DESCRIPTION("PF_CAN broadcast manager protocol");
8685 MODULE_LICENSE("Dual BSD/GPL");
8786 MODULE_AUTHOR("Oliver Hartkopp <oliver.hartkopp@volkswagen.de>");
8887 MODULE_ALIAS("can-proto-2");
88
+
89
+#define BCM_MIN_NAMELEN CAN_REQUIRED_SIZE(struct sockaddr_can, can_ifindex)
8990
9091 /*
9192 * easy access to the first 64 bit of can(fd)_frame payload. cp->data is
....@@ -99,6 +100,7 @@
99100
100101 struct bcm_op {
101102 struct list_head list;
103
+ struct rcu_head rcu;
102104 int ifindex;
103105 canid_t can_id;
104106 u32 flags;
....@@ -272,6 +274,7 @@
272274 struct sk_buff *skb;
273275 struct net_device *dev;
274276 struct canfd_frame *cf = op->frames + op->cfsiz * op->currframe;
277
+ int err;
275278
276279 /* no target device? => exit */
277280 if (!op->ifindex)
....@@ -296,11 +299,11 @@
296299 /* send with loopback */
297300 skb->dev = dev;
298301 can_skb_set_owner(skb, op->sk);
299
- can_send(skb, 1);
302
+ err = can_send(skb, 1);
303
+ if (!err)
304
+ op->frames_abs++;
300305
301
- /* update statistics */
302306 op->currframe++;
303
- op->frames_abs++;
304307
305308 /* reached last frame? */
306309 if (op->currframe >= op->nframes)
....@@ -717,10 +720,9 @@
717720 return NULL;
718721 }
719722
720
-static void bcm_remove_op(struct bcm_op *op)
723
+static void bcm_free_op_rcu(struct rcu_head *rcu_head)
721724 {
722
- hrtimer_cancel(&op->timer);
723
- hrtimer_cancel(&op->thrtimer);
725
+ struct bcm_op *op = container_of(rcu_head, struct bcm_op, rcu);
724726
725727 if ((op->frames) && (op->frames != &op->sframe))
726728 kfree(op->frames);
....@@ -729,6 +731,14 @@
729731 kfree(op->last_frames);
730732
731733 kfree(op);
734
+}
735
+
736
+static void bcm_remove_op(struct bcm_op *op)
737
+{
738
+ hrtimer_cancel(&op->timer);
739
+ hrtimer_cancel(&op->thrtimer);
740
+
741
+ call_rcu(&op->rcu, bcm_free_op_rcu);
732742 }
733743
734744 static void bcm_rx_unreg(struct net_device *dev, struct bcm_op *op)
....@@ -755,6 +765,9 @@
755765 list_for_each_entry_safe(op, n, ops, list) {
756766 if ((op->can_id == mh->can_id) && (op->ifindex == ifindex) &&
757767 (op->flags & CAN_FD_FRAME) == (mh->flags & CAN_FD_FRAME)) {
768
+
769
+ /* disable automatic timer on frame reception */
770
+ op->flags |= RX_NO_AUTOTIMER;
758771
759772 /*
760773 * Don't care if we're bound or not (due to netdev
....@@ -784,7 +797,6 @@
784797 bcm_rx_handler, op);
785798
786799 list_del(&op->list);
787
- synchronize_rcu();
788800 bcm_remove_op(op);
789801 return 1; /* done */
790802 }
....@@ -924,6 +936,8 @@
924936
925937 cf = op->frames + op->cfsiz * i;
926938 err = memcpy_from_msg((u8 *)cf, msg, op->cfsiz);
939
+ if (err < 0)
940
+ goto free_op;
927941
928942 if (op->flags & CAN_FD_FRAME) {
929943 if (cf->len > 64)
....@@ -933,12 +947,8 @@
933947 err = -EINVAL;
934948 }
935949
936
- if (err < 0) {
937
- if (op->frames != &op->sframe)
938
- kfree(op->frames);
939
- kfree(op);
940
- return err;
941
- }
950
+ if (err < 0)
951
+ goto free_op;
942952
943953 if (msg_head->flags & TX_CP_CAN_ID) {
944954 /* copy can_id into frame */
....@@ -1009,6 +1019,12 @@
10091019 bcm_tx_start_timer(op);
10101020
10111021 return msg_head->nframes * op->cfsiz + MHSIZ;
1022
+
1023
+free_op:
1024
+ if (op->frames != &op->sframe)
1025
+ kfree(op->frames);
1026
+ kfree(op);
1027
+ return err;
10121028 }
10131029
10141030 /*
....@@ -1301,7 +1317,7 @@
13011317 /* no bound device as default => check msg_name */
13021318 DECLARE_SOCKADDR(struct sockaddr_can *, addr, msg->msg_name);
13031319
1304
- if (msg->msg_namelen < sizeof(*addr))
1320
+ if (msg->msg_namelen < BCM_MIN_NAMELEN)
13051321 return -EINVAL;
13061322
13071323 if (addr->can_family != AF_CAN)
....@@ -1505,6 +1521,12 @@
15051521
15061522 lock_sock(sk);
15071523
1524
+#if IS_ENABLED(CONFIG_PROC_FS)
1525
+ /* remove procfs entry */
1526
+ if (net->can.bcmproc_dir && bo->bcm_proc_read)
1527
+ remove_proc_entry(bo->procname, net->can.bcmproc_dir);
1528
+#endif /* CONFIG_PROC_FS */
1529
+
15081530 list_for_each_entry_safe(op, next, &bo->tx_ops, list)
15091531 bcm_remove_op(op);
15101532
....@@ -1540,12 +1562,6 @@
15401562 list_for_each_entry_safe(op, next, &bo->rx_ops, list)
15411563 bcm_remove_op(op);
15421564
1543
-#if IS_ENABLED(CONFIG_PROC_FS)
1544
- /* remove procfs entry */
1545
- if (net->can.bcmproc_dir && bo->bcm_proc_read)
1546
- remove_proc_entry(bo->procname, net->can.bcmproc_dir);
1547
-#endif /* CONFIG_PROC_FS */
1548
-
15491565 /* remove device reference */
15501566 if (bo->bound) {
15511567 bo->bound = 0;
....@@ -1570,7 +1586,7 @@
15701586 struct net *net = sock_net(sk);
15711587 int ret = 0;
15721588
1573
- if (len < sizeof(*addr))
1589
+ if (len < BCM_MIN_NAMELEN)
15741590 return -EINVAL;
15751591
15761592 lock_sock(sk);
....@@ -1652,14 +1668,21 @@
16521668 sock_recv_ts_and_drops(msg, sk, skb);
16531669
16541670 if (msg->msg_name) {
1655
- __sockaddr_check_size(sizeof(struct sockaddr_can));
1656
- msg->msg_namelen = sizeof(struct sockaddr_can);
1671
+ __sockaddr_check_size(BCM_MIN_NAMELEN);
1672
+ msg->msg_namelen = BCM_MIN_NAMELEN;
16571673 memcpy(msg->msg_name, skb->cb, msg->msg_namelen);
16581674 }
16591675
16601676 skb_free_datagram(sk, skb);
16611677
16621678 return size;
1679
+}
1680
+
1681
+static int bcm_sock_no_ioctlcmd(struct socket *sock, unsigned int cmd,
1682
+ unsigned long arg)
1683
+{
1684
+ /* no ioctls for socket layer -> hand it down to NIC layer */
1685
+ return -ENOIOCTLCMD;
16631686 }
16641687
16651688 static const struct proto_ops bcm_ops = {
....@@ -1671,11 +1694,10 @@
16711694 .accept = sock_no_accept,
16721695 .getname = sock_no_getname,
16731696 .poll = datagram_poll,
1674
- .ioctl = can_ioctl, /* use can_ioctl() from af_can.c */
1697
+ .ioctl = bcm_sock_no_ioctlcmd,
1698
+ .gettstamp = sock_gettstamp,
16751699 .listen = sock_no_listen,
16761700 .shutdown = sock_no_shutdown,
1677
- .setsockopt = sock_no_setsockopt,
1678
- .getsockopt = sock_no_getsockopt,
16791701 .sendmsg = bcm_sendmsg,
16801702 .recvmsg = bcm_recvmsg,
16811703 .mmap = sock_no_mmap,
....@@ -1728,7 +1750,7 @@
17281750 {
17291751 int err;
17301752
1731
- pr_info("can: broadcast manager protocol (rev " CAN_BCM_VERSION " t)\n");
1753
+ pr_info("can: broadcast manager protocol\n");
17321754
17331755 err = can_proto_register(&bcm_can_proto);
17341756 if (err < 0) {