Skip to content

Commit

Permalink
tun: fix a memory leak for tfile->tx_array
Browse files Browse the repository at this point in the history
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]>
  • Loading branch information
congwang authored and davem330 committed Jan 17, 2018
1 parent 8cbab92 commit 4df0bfc
Showing 1 changed file with 13 additions and 2 deletions.
15 changes: 13 additions & 2 deletions drivers/net/tun.c
Original file line number Diff line number Diff line change
Expand Up @@ -611,6 +611,14 @@ static void tun_queue_purge(struct tun_file *tfile)
skb_queue_purge(&tfile->sk.sk_error_queue);
}

static void tun_cleanup_tx_array(struct tun_file *tfile)
{
if (tfile->tx_array.ring.queue) {
skb_array_cleanup(&tfile->tx_array);
memset(&tfile->tx_array, 0, sizeof(tfile->tx_array));
}
}

static void __tun_detach(struct tun_file *tfile, bool clean)
{
struct tun_file *ntfile;
Expand Down Expand Up @@ -657,8 +665,7 @@ static void __tun_detach(struct tun_file *tfile, bool clean)
tun->dev->reg_state == NETREG_REGISTERED)
unregister_netdevice(tun->dev);
}
if (tun)
skb_array_cleanup(&tfile->tx_array);
tun_cleanup_tx_array(tfile);
sock_put(&tfile->sk);
}
}
Expand Down Expand Up @@ -700,11 +707,13 @@ static void tun_detach_all(struct net_device *dev)
/* Drop read queue */
tun_queue_purge(tfile);
sock_put(&tfile->sk);
tun_cleanup_tx_array(tfile);
}
list_for_each_entry_safe(tfile, tmp, &tun->disabled, next) {
tun_enable_queue(tfile);
tun_queue_purge(tfile);
sock_put(&tfile->sk);
tun_cleanup_tx_array(tfile);
}
BUG_ON(tun->numdisabled != 0);

Expand Down Expand Up @@ -2851,6 +2860,8 @@ static int tun_chr_open(struct inode *inode, struct file * file)

sock_set_flag(&tfile->sk, SOCK_ZEROCOPY);

memset(&tfile->tx_array, 0, sizeof(tfile->tx_array));

return 0;
}

Expand Down

0 comments on commit 4df0bfc

Please sign in to comment.