diff options
author | Xin Long <lucien.xin@gmail.com> | 2020-08-20 10:34:47 +0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2020-08-27 10:31:48 +0300 |
commit | 828fd2e892b03d05e9f573839e7b2d27835703bd (patch) | |
tree | 67e2d921619e80264118b05efe09b37a8ddc6abf | |
parent | 22f2be57784e95210a2b4e732fac586f1c08abbe (diff) | |
download | linux-828fd2e892b03d05e9f573839e7b2d27835703bd.tar.xz |
tipc: call rcu_read_lock() in tipc_aead_encrypt_done()
[ Upstream commit f6db9096416209474090d64d8284e7c16c3d8873 ]
b->media->send_msg() requires rcu_read_lock(), as we can see
elsewhere in tipc, tipc_bearer_xmit, tipc_bearer_xmit_skb
and tipc_bearer_bc_xmit().
Syzbot has reported this issue as:
net/tipc/bearer.c:466 suspicious rcu_dereference_check() usage!
Workqueue: cryptd cryptd_queue_worker
Call Trace:
tipc_l2_send_msg+0x354/0x420 net/tipc/bearer.c:466
tipc_aead_encrypt_done+0x204/0x3a0 net/tipc/crypto.c:761
cryptd_aead_crypt+0xe8/0x1d0 crypto/cryptd.c:739
cryptd_queue_worker+0x118/0x1b0 crypto/cryptd.c:181
process_one_work+0x94c/0x1670 kernel/workqueue.c:2269
worker_thread+0x64c/0x1120 kernel/workqueue.c:2415
kthread+0x3b5/0x4a0 kernel/kthread.c:291
ret_from_fork+0x1f/0x30 arch/x86/entry/entry_64.S:293
So fix it by calling rcu_read_lock() in tipc_aead_encrypt_done()
for b->media->send_msg().
Fixes: fc1b6d6de220 ("tipc: introduce TIPC encryption & authentication")
Reported-by: syzbot+47bbc6b678d317cccbe0@syzkaller.appspotmail.com
Signed-off-by: Xin Long <lucien.xin@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | net/tipc/crypto.c | 2 |
1 files changed, 2 insertions, 0 deletions
diff --git a/net/tipc/crypto.c b/net/tipc/crypto.c index c8c47fc72653..d6426b6cc9c5 100644 --- a/net/tipc/crypto.c +++ b/net/tipc/crypto.c @@ -757,10 +757,12 @@ static void tipc_aead_encrypt_done(struct crypto_async_request *base, int err) switch (err) { case 0: this_cpu_inc(tx->stats->stat[STAT_ASYNC_OK]); + rcu_read_lock(); if (likely(test_bit(0, &b->up))) b->media->send_msg(net, skb, b, &tx_ctx->dst); else kfree_skb(skb); + rcu_read_unlock(); break; case -EINPROGRESS: return; |