Skip to content

Commit 2cc683e

Browse files
Tom Herbertdavem330
authored andcommitted
kcm: lock lower socket in kcm_attach
Need to lock lower socket in order to provide mutual exclusion with kcm_unattach. v2: Add Reported-by for syzbot Fixes: ab7ac4e ("kcm: Kernel Connection Multiplexor module") Reported-by: syzbot+ea75c0ffcd353d32515f064aaebefc5279e6161e@syzkaller.appspotmail.com Signed-off-by: Tom Herbert <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent e693be2 commit 2cc683e

File tree

1 file changed

+23
-10
lines changed

1 file changed

+23
-10
lines changed

net/kcm/kcmsock.c

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1381,24 +1381,32 @@ static int kcm_attach(struct socket *sock, struct socket *csock,
13811381
.parse_msg = kcm_parse_func_strparser,
13821382
.read_sock_done = kcm_read_sock_done,
13831383
};
1384-
int err;
1384+
int err = 0;
13851385

13861386
csk = csock->sk;
13871387
if (!csk)
13881388
return -EINVAL;
13891389

1390+
lock_sock(csk);
1391+
13901392
/* Only allow TCP sockets to be attached for now */
13911393
if ((csk->sk_family != AF_INET && csk->sk_family != AF_INET6) ||
1392-
csk->sk_protocol != IPPROTO_TCP)
1393-
return -EOPNOTSUPP;
1394+
csk->sk_protocol != IPPROTO_TCP) {
1395+
err = -EOPNOTSUPP;
1396+
goto out;
1397+
}
13941398

13951399
/* Don't allow listeners or closed sockets */
1396-
if (csk->sk_state == TCP_LISTEN || csk->sk_state == TCP_CLOSE)
1397-
return -EOPNOTSUPP;
1400+
if (csk->sk_state == TCP_LISTEN || csk->sk_state == TCP_CLOSE) {
1401+
err = -EOPNOTSUPP;
1402+
goto out;
1403+
}
13981404

13991405
psock = kmem_cache_zalloc(kcm_psockp, GFP_KERNEL);
1400-
if (!psock)
1401-
return -ENOMEM;
1406+
if (!psock) {
1407+
err = -ENOMEM;
1408+
goto out;
1409+
}
14021410

14031411
psock->mux = mux;
14041412
psock->sk = csk;
@@ -1407,7 +1415,7 @@ static int kcm_attach(struct socket *sock, struct socket *csock,
14071415
err = strp_init(&psock->strp, csk, &cb);
14081416
if (err) {
14091417
kmem_cache_free(kcm_psockp, psock);
1410-
return err;
1418+
goto out;
14111419
}
14121420

14131421
write_lock_bh(&csk->sk_callback_lock);
@@ -1419,7 +1427,8 @@ static int kcm_attach(struct socket *sock, struct socket *csock,
14191427
write_unlock_bh(&csk->sk_callback_lock);
14201428
strp_done(&psock->strp);
14211429
kmem_cache_free(kcm_psockp, psock);
1422-
return -EALREADY;
1430+
err = -EALREADY;
1431+
goto out;
14231432
}
14241433

14251434
psock->save_data_ready = csk->sk_data_ready;
@@ -1455,7 +1464,10 @@ static int kcm_attach(struct socket *sock, struct socket *csock,
14551464
/* Schedule RX work in case there are already bytes queued */
14561465
strp_check_rcv(&psock->strp);
14571466

1458-
return 0;
1467+
out:
1468+
release_sock(csk);
1469+
1470+
return err;
14591471
}
14601472

14611473
static int kcm_attach_ioctl(struct socket *sock, struct kcm_attach *info)
@@ -1507,6 +1519,7 @@ static void kcm_unattach(struct kcm_psock *psock)
15071519

15081520
if (WARN_ON(psock->rx_kcm)) {
15091521
write_unlock_bh(&csk->sk_callback_lock);
1522+
release_sock(csk);
15101523
return;
15111524
}
15121525

0 commit comments

Comments
 (0)