summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTavian Barnes <tavianator@tavianator.com>2023-10-12 15:50:59 -0400
committerTavian Barnes <tavianator@tavianator.com>2023-10-12 15:50:59 -0400
commitd64a32e03b4d9a1336ebfa66d7d08d96e9847a6a (patch)
tree9ff9c5a4831e2cdb37cb9771dc9fb254216b7042 /src
parent773f4a446f03da62d88e6d17be49fdc0a3e38465 (diff)
downloadbfs-d64a32e03b4d9a1336ebfa66d7d08d96e9847a6a.tar.xz
bftw: Make sure we don't close a directory while we unwrap it
bftw_cache_reserve() can lead to bftw_cache_pop(), which could close the directory we're trying to unwrap! If that happened, we would try dup_cloexec(-1), which would fail with EBADF, so there was no observable bug. But it's better to avoid the whole situation.
Diffstat (limited to 'src')
-rw-r--r--src/bftw.c8
1 files changed, 6 insertions, 2 deletions
diff --git a/src/bftw.c b/src/bftw.c
index 1995e12..06a0085 100644
--- a/src/bftw.c
+++ b/src/bftw.c
@@ -811,8 +811,12 @@ static int bftw_unwrapdir(struct bftw_state *state, struct bftw_file *file) {
return bftw_close(state, file);
}
- if (bftw_cache_reserve(state) != 0) {
- return -1;
+ // Make room for dup()
+ bftw_cache_pin(cache, file);
+ int ret = bftw_cache_reserve(state);
+ bftw_cache_unpin(cache, file);
+ if (ret != 0) {
+ return ret;
}
int fd = dup_cloexec(file->fd);