Skip to content

Commit 3aaea88

Browse files
committed
Merge branch 'atm-clip-fix-infinite-recursion-potential-null-ptr-deref-and-memleak'
Kuniyuki Iwashima says: ==================== atm: clip: Fix infinite recursion, potential null-ptr-deref, and memleak. Patch 1 fixes racy access to atmarpd found while checking RTNL usage in clip.c. Patch 2 fixes memory leak by ioctl(ATMARP_MKIP) and ioctl(ATMARPD_CTRL). Patch 3 fixes infinite recursive call of clip_vcc->old_push(), which was reported by syzbot. v1: https://lore.kernel.org/[email protected] ==================== Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
2 parents 3c78f91 + c489f32 commit 3aaea88

File tree

1 file changed

+39
-15
lines changed

1 file changed

+39
-15
lines changed

net/atm/clip.c

Lines changed: 39 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -45,32 +45,44 @@
4545
#include <net/atmclip.h>
4646

4747
static struct net_device *clip_devs;
48-
static struct atm_vcc *atmarpd;
48+
static struct atm_vcc __rcu *atmarpd;
49+
static DEFINE_MUTEX(atmarpd_lock);
4950
static struct timer_list idle_timer;
5051
static const struct neigh_ops clip_neigh_ops;
5152

5253
static int to_atmarpd(enum atmarp_ctrl_type type, int itf, __be32 ip)
5354
{
5455
struct sock *sk;
5556
struct atmarp_ctrl *ctrl;
57+
struct atm_vcc *vcc;
5658
struct sk_buff *skb;
59+
int err = 0;
5760

5861
pr_debug("(%d)\n", type);
59-
if (!atmarpd)
60-
return -EUNATCH;
62+
63+
rcu_read_lock();
64+
vcc = rcu_dereference(atmarpd);
65+
if (!vcc) {
66+
err = -EUNATCH;
67+
goto unlock;
68+
}
6169
skb = alloc_skb(sizeof(struct atmarp_ctrl), GFP_ATOMIC);
62-
if (!skb)
63-
return -ENOMEM;
70+
if (!skb) {
71+
err = -ENOMEM;
72+
goto unlock;
73+
}
6474
ctrl = skb_put(skb, sizeof(struct atmarp_ctrl));
6575
ctrl->type = type;
6676
ctrl->itf_num = itf;
6777
ctrl->ip = ip;
68-
atm_force_charge(atmarpd, skb->truesize);
78+
atm_force_charge(vcc, skb->truesize);
6979

70-
sk = sk_atm(atmarpd);
80+
sk = sk_atm(vcc);
7181
skb_queue_tail(&sk->sk_receive_queue, skb);
7282
sk->sk_data_ready(sk);
73-
return 0;
83+
unlock:
84+
rcu_read_unlock();
85+
return err;
7486
}
7587

7688
static void link_vcc(struct clip_vcc *clip_vcc, struct atmarp_entry *entry)
@@ -417,6 +429,8 @@ static int clip_mkip(struct atm_vcc *vcc, int timeout)
417429

418430
if (!vcc->push)
419431
return -EBADFD;
432+
if (vcc->user_back)
433+
return -EINVAL;
420434
clip_vcc = kmalloc(sizeof(struct clip_vcc), GFP_KERNEL);
421435
if (!clip_vcc)
422436
return -ENOMEM;
@@ -607,10 +621,12 @@ static void atmarpd_close(struct atm_vcc *vcc)
607621
{
608622
pr_debug("\n");
609623

610-
rtnl_lock();
611-
atmarpd = NULL;
624+
mutex_lock(&atmarpd_lock);
625+
RCU_INIT_POINTER(atmarpd, NULL);
626+
mutex_unlock(&atmarpd_lock);
627+
628+
synchronize_rcu();
612629
skb_queue_purge(&sk_atm(vcc)->sk_receive_queue);
613-
rtnl_unlock();
614630

615631
pr_debug("(done)\n");
616632
module_put(THIS_MODULE);
@@ -631,15 +647,18 @@ static struct atm_dev atmarpd_dev = {
631647

632648
static int atm_init_atmarp(struct atm_vcc *vcc)
633649
{
634-
rtnl_lock();
650+
if (vcc->push == clip_push)
651+
return -EINVAL;
652+
653+
mutex_lock(&atmarpd_lock);
635654
if (atmarpd) {
636-
rtnl_unlock();
655+
mutex_unlock(&atmarpd_lock);
637656
return -EADDRINUSE;
638657
}
639658

640659
mod_timer(&idle_timer, jiffies + CLIP_CHECK_INTERVAL * HZ);
641660

642-
atmarpd = vcc;
661+
rcu_assign_pointer(atmarpd, vcc);
643662
set_bit(ATM_VF_META, &vcc->flags);
644663
set_bit(ATM_VF_READY, &vcc->flags);
645664
/* allow replies and avoid getting closed if signaling dies */
@@ -648,13 +667,14 @@ static int atm_init_atmarp(struct atm_vcc *vcc)
648667
vcc->push = NULL;
649668
vcc->pop = NULL; /* crash */
650669
vcc->push_oam = NULL; /* crash */
651-
rtnl_unlock();
670+
mutex_unlock(&atmarpd_lock);
652671
return 0;
653672
}
654673

655674
static int clip_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
656675
{
657676
struct atm_vcc *vcc = ATM_SD(sock);
677+
struct sock *sk = sock->sk;
658678
int err = 0;
659679

660680
switch (cmd) {
@@ -675,14 +695,18 @@ static int clip_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
675695
err = clip_create(arg);
676696
break;
677697
case ATMARPD_CTRL:
698+
lock_sock(sk);
678699
err = atm_init_atmarp(vcc);
679700
if (!err) {
680701
sock->state = SS_CONNECTED;
681702
__module_get(THIS_MODULE);
682703
}
704+
release_sock(sk);
683705
break;
684706
case ATMARP_MKIP:
707+
lock_sock(sk);
685708
err = clip_mkip(vcc, arg);
709+
release_sock(sk);
686710
break;
687711
case ATMARP_SETENTRY:
688712
err = clip_setentry(vcc, (__force __be32)arg);

0 commit comments

Comments
 (0)