From: Jakub Kicinski kuba@kernel.org
stable inclusion from stable-v5.10.129 commit c70ca16f72b21d5e33d030b4f2da6df3abf0f293 category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I5YNDQ
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=...
--------------------------------
commit a8fc8cb5692aebb9c6f7afd4265366d25dcd1d01 upstream.
While looking at a syzbot report I noticed the NAPI only gets disabled before it's deleted. I think that user can detach the queue before destroying the device and the NAPI will never be stopped.
Fixes: 943170998b20 ("tun: enable NAPI for TUN/TAP driver") Acked-by: Petar Penkov ppenkov@aviatrix.com Link: https://lore.kernel.org/r/20220623042105.2274812-1-kuba@kernel.org Signed-off-by: Jakub Kicinski kuba@kernel.org Signed-off-by: Greg Kroah-Hartman gregkh@linuxfoundation.org Signed-off-by: Zheng Zengkai zhengzengkai@huawei.com Reviewed-by: Wei Li liwei391@huawei.com --- drivers/net/tun.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/drivers/net/tun.c b/drivers/net/tun.c index 44cc676d17c8..463eae12dd29 100644 --- a/drivers/net/tun.c +++ b/drivers/net/tun.c @@ -285,6 +285,12 @@ static void tun_napi_init(struct tun_struct *tun, struct tun_file *tfile, } }
+static void tun_napi_enable(struct tun_file *tfile) +{ + if (tfile->napi_enabled) + napi_enable(&tfile->napi); +} + static void tun_napi_disable(struct tun_file *tfile) { if (tfile->napi_enabled) @@ -665,8 +671,10 @@ static void __tun_detach(struct tun_file *tfile, bool clean) if (clean) { RCU_INIT_POINTER(tfile->tun, NULL); sock_put(&tfile->sk); - } else + } else { tun_disable_queue(tun, tfile); + tun_napi_disable(tfile); + }
synchronize_net(); tun_flow_delete_by_queue(tun, tun->numqueues + 1); @@ -820,6 +828,7 @@ static int tun_attach(struct tun_struct *tun, struct file *file,
if (tfile->detached) { tun_enable_queue(tfile); + tun_napi_enable(tfile); } else { sock_hold(&tfile->sk); tun_napi_init(tun, tfile, napi, napi_frags);