From 8cee8c278a88d134ce2a0ece12b31f83e261677e Mon Sep 17 00:00:00 2001 From: Rob Landley Date: Mon, 6 Feb 2023 06:05:36 -0600 Subject: [PATCH] Fix a couple tar --sort leaks. --- lib/dirtree.c | 6 ++++-- toys/posix/tar.c | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/dirtree.c b/lib/dirtree.c index 98932a07..00de64e4 100644 --- a/lib/dirtree.c +++ b/lib/dirtree.c @@ -125,6 +125,7 @@ static struct dirtree *dirtree_handle_callback(struct dirtree *new, flags = callback(new); if (S_ISDIR(new->st.st_mode) && (flags & df)) { + // TODO: check openat returned fd for errors... and do what about it? if (*new->name) fd = openat(dirtree_parentfd(new), new->name, O_CLOEXEC); if (flags&DIRTREE_BREADTH) { new->again |= DIRTREE_BREADTH; @@ -133,10 +134,11 @@ static struct dirtree *dirtree_handle_callback(struct dirtree *new, return DIRTREE_ABORTVAL; } flags = dirtree_recurse(new, callback, fd, flags); + close(fd); } // Free node that didn't request saving and has no saved children. - if (!new->child && !(flags & DIRTREE_SAVE) && (!new->parent || !(new->parent->again&DIRTREE_BREADTH))) { + if (!new->child && !(flags & DIRTREE_SAVE)) { free(new); new = 0; } @@ -145,7 +147,7 @@ static struct dirtree *dirtree_handle_callback(struct dirtree *new, } // Recursively read/process children of directory node, filtering through -// callback(). Uses and closes supplied ->dirfd. +// callback(). int dirtree_recurse(struct dirtree *node, int (*callback)(struct dirtree *node), int dirfd, int flags) diff --git a/toys/posix/tar.c b/toys/posix/tar.c index 1b325309..3a399863 100644 --- a/toys/posix/tar.c +++ b/toys/posix/tar.c @@ -287,7 +287,7 @@ static int add_to_tar(struct dirtree *node) free(name); return DIRTREE_BREADTH; - } else if (node->again&DIRTREE_BREADTH) { + } else if ((node->again&DIRTREE_BREADTH) && node->child) { struct dirtree *dt, **sort = xmalloc(sizeof(void *)*node->extra); for (node->extra = 0, dt = node->child; dt; dt = dt->next) -- 2.39.2