Skip to content

Commit 51c1f51

Browse files
congwanggregkh
authored andcommitted
tun: fix a memory leak for tfile->tx_array
[ Upstream commit 4df0bfc ] tfile->tun could be detached before we close the tun fd, via tun_detach_all(), so it should not be used to check for tfile->tx_array. As Jason suggested, we probably have to clean it up unconditionally both in __tun_deatch() and tun_detach_all(), but this requires to check if it is initialized or not. Currently skb_array_cleanup() doesn't have such a check, so I check it in the caller and introduce a helper function, it is a bit ugly but we can always improve it in net-next. Reported-by: Dmitry Vyukov <[email protected]> Fixes: 1576d98 ("tun: switch to use skb array for tx") Cc: Jason Wang <[email protected]> Signed-off-by: Cong Wang <[email protected]> Signed-off-by: David S. Miller <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 8496f7d commit 51c1f51

File tree

1 file changed

+13
-2
lines changed

1 file changed

+13
-2
lines changed

drivers/net/tun.c

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -534,6 +534,14 @@ static void tun_queue_purge(struct tun_file *tfile)
534534
skb_queue_purge(&tfile->sk.sk_error_queue);
535535
}
536536

537+
static void tun_cleanup_tx_array(struct tun_file *tfile)
538+
{
539+
if (tfile->tx_array.ring.queue) {
540+
skb_array_cleanup(&tfile->tx_array);
541+
memset(&tfile->tx_array, 0, sizeof(tfile->tx_array));
542+
}
543+
}
544+
537545
static void __tun_detach(struct tun_file *tfile, bool clean)
538546
{
539547
struct tun_file *ntfile;
@@ -575,8 +583,7 @@ static void __tun_detach(struct tun_file *tfile, bool clean)
575583
tun->dev->reg_state == NETREG_REGISTERED)
576584
unregister_netdevice(tun->dev);
577585
}
578-
if (tun)
579-
skb_array_cleanup(&tfile->tx_array);
586+
tun_cleanup_tx_array(tfile);
580587
sock_put(&tfile->sk);
581588
}
582589
}
@@ -616,11 +623,13 @@ static void tun_detach_all(struct net_device *dev)
616623
/* Drop read queue */
617624
tun_queue_purge(tfile);
618625
sock_put(&tfile->sk);
626+
tun_cleanup_tx_array(tfile);
619627
}
620628
list_for_each_entry_safe(tfile, tmp, &tun->disabled, next) {
621629
tun_enable_queue(tfile);
622630
tun_queue_purge(tfile);
623631
sock_put(&tfile->sk);
632+
tun_cleanup_tx_array(tfile);
624633
}
625634
BUG_ON(tun->numdisabled != 0);
626635

@@ -2624,6 +2633,8 @@ static int tun_chr_open(struct inode *inode, struct file * file)
26242633

26252634
sock_set_flag(&tfile->sk, SOCK_ZEROCOPY);
26262635

2636+
memset(&tfile->tx_array, 0, sizeof(tfile->tx_array));
2637+
26272638
return 0;
26282639
}
26292640

0 commit comments

Comments
 (0)