Skip to content

Commit

Permalink
tun: fix tun_link leak in dump_tun_link
Browse files Browse the repository at this point in the history
coverity CID 389205:

452int dump_tun_link(NetDeviceEntry *nde, struct cr_imgset *fds, struct nlattr **info)
453{
...
458        struct tun_link *tl;
...
   2. alloc_fn: Storage is returned from allocation function get_tun_link_fd. [show details]
   3. var_assign: Assigning: tl = storage returned from get_tun_link_fd(nde->name, nde->peer_nsid, tle.flags).
475        tl = get_tun_link_fd(nde->name, nde->peer_nsid, tle.flags);
   4. Condition !tl, taking false branch.
476        if (!tl)
477                return ret;
478
479        tle.vnethdr = tl->dmp.vnethdr;
480        tle.sndbuf = tl->dmp.sndbuf;
481
482        nde->tun = &tle;
   CID 389205 (#1 of 1): Resource leak (RESOURCE_LEAK)5. leaked_storage: Variable tl going out of scope leaks the storage it points to.
483        return write_netdev_img(nde, fds, info);
484}

Function get_tun_link_fd() can both return tun_link entry from tun_links
list and a newly allocated one. So we should not free entry if it is
from list and should free it when it is a new one to fix leak.

Signed-off-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
  • Loading branch information
Snorch authored and avagin committed Apr 29, 2022
1 parent 7e9a9dc commit 09fa32a
Showing 1 changed file with 9 additions and 0 deletions.
9 changes: 9 additions & 0 deletions criu/tun.c
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ static struct tun_link *__dump_tun_link_fd(int fd, char *name, unsigned ns_id, u
goto err;
strlcpy(tl->name, name, sizeof(tl->name));
tl->ns_id = ns_id;
INIT_LIST_HEAD(&tl->l);

if (ioctl(fd, TUNGETVNETHDRSZ, &tl->dmp.vnethdr) < 0) {
pr_perror("Can't dump vnethdr size for %s", name);
Expand Down Expand Up @@ -479,6 +480,14 @@ int dump_tun_link(NetDeviceEntry *nde, struct cr_imgset *fds, struct nlattr **in
tle.vnethdr = tl->dmp.vnethdr;
tle.sndbuf = tl->dmp.sndbuf;

/*
* Function get_tun_link_fd() can return either entry
* from tun_links list or a newly allocated one, need to
* free it only if not in list.
*/
if (list_empty(&tl->l))
xfree(tl);

nde->tun = &tle;
return write_netdev_img(nde, fds, info);
}
Expand Down

0 comments on commit 09fa32a

Please sign in to comment.