Skip to content

Commit e82a35a

Browse files
committed
Merge tag 'linux-can-fixes-for-5.13-20210616' of git://git.kernel.org/pub/scm/linux/kernel/git/mkl/linux-can
Marc Kleine-Budde says: ==================== pull-request: can 2021-06-16 this is a pull request of 4 patches for net/master. The first patch is by Oleksij Rempel and fixes a Use-after-Free found by syzbot in the j1939 stack. The next patch is by Tetsuo Handa and fixes hung task detected by syzbot in the bcm, raw and isotp protocols. Norbert Slusarek's patch fixes a infoleak in bcm's struct bcm_msg_head. Pavel Skripkin's patch fixes a memory leak in the mcba_usb driver. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
2 parents d8e2973 + 91c0255 commit e82a35a

File tree

5 files changed

+200
-56
lines changed

5 files changed

+200
-56
lines changed

drivers/net/can/usb/mcba_usb.c

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ struct mcba_priv {
8282
bool can_ka_first_pass;
8383
bool can_speed_check;
8484
atomic_t free_ctx_cnt;
85+
void *rxbuf[MCBA_MAX_RX_URBS];
86+
dma_addr_t rxbuf_dma[MCBA_MAX_RX_URBS];
8587
};
8688

8789
/* CAN frame */
@@ -633,6 +635,7 @@ static int mcba_usb_start(struct mcba_priv *priv)
633635
for (i = 0; i < MCBA_MAX_RX_URBS; i++) {
634636
struct urb *urb = NULL;
635637
u8 *buf;
638+
dma_addr_t buf_dma;
636639

637640
/* create a URB, and a buffer for it */
638641
urb = usb_alloc_urb(0, GFP_KERNEL);
@@ -642,7 +645,7 @@ static int mcba_usb_start(struct mcba_priv *priv)
642645
}
643646

644647
buf = usb_alloc_coherent(priv->udev, MCBA_USB_RX_BUFF_SIZE,
645-
GFP_KERNEL, &urb->transfer_dma);
648+
GFP_KERNEL, &buf_dma);
646649
if (!buf) {
647650
netdev_err(netdev, "No memory left for USB buffer\n");
648651
usb_free_urb(urb);
@@ -661,11 +664,14 @@ static int mcba_usb_start(struct mcba_priv *priv)
661664
if (err) {
662665
usb_unanchor_urb(urb);
663666
usb_free_coherent(priv->udev, MCBA_USB_RX_BUFF_SIZE,
664-
buf, urb->transfer_dma);
667+
buf, buf_dma);
665668
usb_free_urb(urb);
666669
break;
667670
}
668671

672+
priv->rxbuf[i] = buf;
673+
priv->rxbuf_dma[i] = buf_dma;
674+
669675
/* Drop reference, USB core will take care of freeing it */
670676
usb_free_urb(urb);
671677
}
@@ -708,7 +714,14 @@ static int mcba_usb_open(struct net_device *netdev)
708714

709715
static void mcba_urb_unlink(struct mcba_priv *priv)
710716
{
717+
int i;
718+
711719
usb_kill_anchored_urbs(&priv->rx_submitted);
720+
721+
for (i = 0; i < MCBA_MAX_RX_URBS; ++i)
722+
usb_free_coherent(priv->udev, MCBA_USB_RX_BUFF_SIZE,
723+
priv->rxbuf[i], priv->rxbuf_dma[i]);
724+
712725
usb_kill_anchored_urbs(&priv->tx_submitted);
713726
}
714727

net/can/bcm.c

Lines changed: 49 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -125,14 +125,18 @@ struct bcm_sock {
125125
struct sock sk;
126126
int bound;
127127
int ifindex;
128-
struct notifier_block notifier;
128+
struct list_head notifier;
129129
struct list_head rx_ops;
130130
struct list_head tx_ops;
131131
unsigned long dropped_usr_msgs;
132132
struct proc_dir_entry *bcm_proc_read;
133133
char procname [32]; /* inode number in decimal with \0 */
134134
};
135135

136+
static LIST_HEAD(bcm_notifier_list);
137+
static DEFINE_SPINLOCK(bcm_notifier_lock);
138+
static struct bcm_sock *bcm_busy_notifier;
139+
136140
static inline struct bcm_sock *bcm_sk(const struct sock *sk)
137141
{
138142
return (struct bcm_sock *)sk;
@@ -402,6 +406,7 @@ static enum hrtimer_restart bcm_tx_timeout_handler(struct hrtimer *hrtimer)
402406
if (!op->count && (op->flags & TX_COUNTEVT)) {
403407

404408
/* create notification to user */
409+
memset(&msg_head, 0, sizeof(msg_head));
405410
msg_head.opcode = TX_EXPIRED;
406411
msg_head.flags = op->flags;
407412
msg_head.count = op->count;
@@ -439,6 +444,7 @@ static void bcm_rx_changed(struct bcm_op *op, struct canfd_frame *data)
439444
/* this element is not throttled anymore */
440445
data->flags &= (BCM_CAN_FLAGS_MASK|RX_RECV);
441446

447+
memset(&head, 0, sizeof(head));
442448
head.opcode = RX_CHANGED;
443449
head.flags = op->flags;
444450
head.count = op->count;
@@ -560,6 +566,7 @@ static enum hrtimer_restart bcm_rx_timeout_handler(struct hrtimer *hrtimer)
560566
}
561567

562568
/* create notification to user */
569+
memset(&msg_head, 0, sizeof(msg_head));
563570
msg_head.opcode = RX_TIMEOUT;
564571
msg_head.flags = op->flags;
565572
msg_head.count = op->count;
@@ -1378,20 +1385,15 @@ static int bcm_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
13781385
/*
13791386
* notification handler for netdevice status changes
13801387
*/
1381-
static int bcm_notifier(struct notifier_block *nb, unsigned long msg,
1382-
void *ptr)
1388+
static void bcm_notify(struct bcm_sock *bo, unsigned long msg,
1389+
struct net_device *dev)
13831390
{
1384-
struct net_device *dev = netdev_notifier_info_to_dev(ptr);
1385-
struct bcm_sock *bo = container_of(nb, struct bcm_sock, notifier);
13861391
struct sock *sk = &bo->sk;
13871392
struct bcm_op *op;
13881393
int notify_enodev = 0;
13891394

13901395
if (!net_eq(dev_net(dev), sock_net(sk)))
1391-
return NOTIFY_DONE;
1392-
1393-
if (dev->type != ARPHRD_CAN)
1394-
return NOTIFY_DONE;
1396+
return;
13951397

13961398
switch (msg) {
13971399

@@ -1426,7 +1428,28 @@ static int bcm_notifier(struct notifier_block *nb, unsigned long msg,
14261428
sk->sk_error_report(sk);
14271429
}
14281430
}
1431+
}
14291432

1433+
static int bcm_notifier(struct notifier_block *nb, unsigned long msg,
1434+
void *ptr)
1435+
{
1436+
struct net_device *dev = netdev_notifier_info_to_dev(ptr);
1437+
1438+
if (dev->type != ARPHRD_CAN)
1439+
return NOTIFY_DONE;
1440+
if (msg != NETDEV_UNREGISTER && msg != NETDEV_DOWN)
1441+
return NOTIFY_DONE;
1442+
if (unlikely(bcm_busy_notifier)) /* Check for reentrant bug. */
1443+
return NOTIFY_DONE;
1444+
1445+
spin_lock(&bcm_notifier_lock);
1446+
list_for_each_entry(bcm_busy_notifier, &bcm_notifier_list, notifier) {
1447+
spin_unlock(&bcm_notifier_lock);
1448+
bcm_notify(bcm_busy_notifier, msg, dev);
1449+
spin_lock(&bcm_notifier_lock);
1450+
}
1451+
bcm_busy_notifier = NULL;
1452+
spin_unlock(&bcm_notifier_lock);
14301453
return NOTIFY_DONE;
14311454
}
14321455

@@ -1446,9 +1469,9 @@ static int bcm_init(struct sock *sk)
14461469
INIT_LIST_HEAD(&bo->rx_ops);
14471470

14481471
/* set notifier */
1449-
bo->notifier.notifier_call = bcm_notifier;
1450-
1451-
register_netdevice_notifier(&bo->notifier);
1472+
spin_lock(&bcm_notifier_lock);
1473+
list_add_tail(&bo->notifier, &bcm_notifier_list);
1474+
spin_unlock(&bcm_notifier_lock);
14521475

14531476
return 0;
14541477
}
@@ -1471,7 +1494,14 @@ static int bcm_release(struct socket *sock)
14711494

14721495
/* remove bcm_ops, timer, rx_unregister(), etc. */
14731496

1474-
unregister_netdevice_notifier(&bo->notifier);
1497+
spin_lock(&bcm_notifier_lock);
1498+
while (bcm_busy_notifier == bo) {
1499+
spin_unlock(&bcm_notifier_lock);
1500+
schedule_timeout_uninterruptible(1);
1501+
spin_lock(&bcm_notifier_lock);
1502+
}
1503+
list_del(&bo->notifier);
1504+
spin_unlock(&bcm_notifier_lock);
14751505

14761506
lock_sock(sk);
14771507

@@ -1692,6 +1722,10 @@ static struct pernet_operations canbcm_pernet_ops __read_mostly = {
16921722
.exit = canbcm_pernet_exit,
16931723
};
16941724

1725+
static struct notifier_block canbcm_notifier = {
1726+
.notifier_call = bcm_notifier
1727+
};
1728+
16951729
static int __init bcm_module_init(void)
16961730
{
16971731
int err;
@@ -1705,12 +1739,14 @@ static int __init bcm_module_init(void)
17051739
}
17061740

17071741
register_pernet_subsys(&canbcm_pernet_ops);
1742+
register_netdevice_notifier(&canbcm_notifier);
17081743
return 0;
17091744
}
17101745

17111746
static void __exit bcm_module_exit(void)
17121747
{
17131748
can_proto_unregister(&bcm_can_proto);
1749+
unregister_netdevice_notifier(&canbcm_notifier);
17141750
unregister_pernet_subsys(&canbcm_pernet_ops);
17151751
}
17161752

net/can/isotp.c

Lines changed: 48 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -143,10 +143,14 @@ struct isotp_sock {
143143
u32 force_tx_stmin;
144144
u32 force_rx_stmin;
145145
struct tpcon rx, tx;
146-
struct notifier_block notifier;
146+
struct list_head notifier;
147147
wait_queue_head_t wait;
148148
};
149149

150+
static LIST_HEAD(isotp_notifier_list);
151+
static DEFINE_SPINLOCK(isotp_notifier_lock);
152+
static struct isotp_sock *isotp_busy_notifier;
153+
150154
static inline struct isotp_sock *isotp_sk(const struct sock *sk)
151155
{
152156
return (struct isotp_sock *)sk;
@@ -1013,7 +1017,14 @@ static int isotp_release(struct socket *sock)
10131017
/* wait for complete transmission of current pdu */
10141018
wait_event_interruptible(so->wait, so->tx.state == ISOTP_IDLE);
10151019

1016-
unregister_netdevice_notifier(&so->notifier);
1020+
spin_lock(&isotp_notifier_lock);
1021+
while (isotp_busy_notifier == so) {
1022+
spin_unlock(&isotp_notifier_lock);
1023+
schedule_timeout_uninterruptible(1);
1024+
spin_lock(&isotp_notifier_lock);
1025+
}
1026+
list_del(&so->notifier);
1027+
spin_unlock(&isotp_notifier_lock);
10171028

10181029
lock_sock(sk);
10191030

@@ -1317,21 +1328,16 @@ static int isotp_getsockopt(struct socket *sock, int level, int optname,
13171328
return 0;
13181329
}
13191330

1320-
static int isotp_notifier(struct notifier_block *nb, unsigned long msg,
1321-
void *ptr)
1331+
static void isotp_notify(struct isotp_sock *so, unsigned long msg,
1332+
struct net_device *dev)
13221333
{
1323-
struct net_device *dev = netdev_notifier_info_to_dev(ptr);
1324-
struct isotp_sock *so = container_of(nb, struct isotp_sock, notifier);
13251334
struct sock *sk = &so->sk;
13261335

13271336
if (!net_eq(dev_net(dev), sock_net(sk)))
1328-
return NOTIFY_DONE;
1329-
1330-
if (dev->type != ARPHRD_CAN)
1331-
return NOTIFY_DONE;
1337+
return;
13321338

13331339
if (so->ifindex != dev->ifindex)
1334-
return NOTIFY_DONE;
1340+
return;
13351341

13361342
switch (msg) {
13371343
case NETDEV_UNREGISTER:
@@ -1357,7 +1363,28 @@ static int isotp_notifier(struct notifier_block *nb, unsigned long msg,
13571363
sk->sk_error_report(sk);
13581364
break;
13591365
}
1366+
}
13601367

1368+
static int isotp_notifier(struct notifier_block *nb, unsigned long msg,
1369+
void *ptr)
1370+
{
1371+
struct net_device *dev = netdev_notifier_info_to_dev(ptr);
1372+
1373+
if (dev->type != ARPHRD_CAN)
1374+
return NOTIFY_DONE;
1375+
if (msg != NETDEV_UNREGISTER && msg != NETDEV_DOWN)
1376+
return NOTIFY_DONE;
1377+
if (unlikely(isotp_busy_notifier)) /* Check for reentrant bug. */
1378+
return NOTIFY_DONE;
1379+
1380+
spin_lock(&isotp_notifier_lock);
1381+
list_for_each_entry(isotp_busy_notifier, &isotp_notifier_list, notifier) {
1382+
spin_unlock(&isotp_notifier_lock);
1383+
isotp_notify(isotp_busy_notifier, msg, dev);
1384+
spin_lock(&isotp_notifier_lock);
1385+
}
1386+
isotp_busy_notifier = NULL;
1387+
spin_unlock(&isotp_notifier_lock);
13611388
return NOTIFY_DONE;
13621389
}
13631390

@@ -1394,8 +1421,9 @@ static int isotp_init(struct sock *sk)
13941421

13951422
init_waitqueue_head(&so->wait);
13961423

1397-
so->notifier.notifier_call = isotp_notifier;
1398-
register_netdevice_notifier(&so->notifier);
1424+
spin_lock(&isotp_notifier_lock);
1425+
list_add_tail(&so->notifier, &isotp_notifier_list);
1426+
spin_unlock(&isotp_notifier_lock);
13991427

14001428
return 0;
14011429
}
@@ -1442,6 +1470,10 @@ static const struct can_proto isotp_can_proto = {
14421470
.prot = &isotp_proto,
14431471
};
14441472

1473+
static struct notifier_block canisotp_notifier = {
1474+
.notifier_call = isotp_notifier
1475+
};
1476+
14451477
static __init int isotp_module_init(void)
14461478
{
14471479
int err;
@@ -1451,13 +1483,16 @@ static __init int isotp_module_init(void)
14511483
err = can_proto_register(&isotp_can_proto);
14521484
if (err < 0)
14531485
pr_err("can: registration of isotp protocol failed\n");
1486+
else
1487+
register_netdevice_notifier(&canisotp_notifier);
14541488

14551489
return err;
14561490
}
14571491

14581492
static __exit void isotp_module_exit(void)
14591493
{
14601494
can_proto_unregister(&isotp_can_proto);
1495+
unregister_netdevice_notifier(&canisotp_notifier);
14611496
}
14621497

14631498
module_init(isotp_module_init);

0 commit comments

Comments
 (0)