summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPanu Matilainen <pmatilai@redhat.com>2022-09-13 10:26:05 +0300
committerPanu Matilainen <pmatilai@redhat.com>2022-09-20 15:07:44 +0300
commitca243dc5f38213b027dace0ee9a0783cd29dd1cf (patch)
treed03a69841938b6f7fdfd10228927b4375dc31c05
parenta3c690508d9a50ee1fe32cf5daea1a5c3046ebc0 (diff)
downloadrpm-ca243dc5f38213b027dace0ee9a0783cd29dd1cf.tar.gz
Fix possible descriptor leak in fsmOpenat()
For the very unlikely case when openat() succeeded but fstatat() doesn't, the directory descriptor may be leaved opened. Rearrange the code a bit to ensure it'll always get closed when appropriate. Suggested-by: Pavel Kopylov <pkopylov@cloudlinux.com> Suggested-by: Dmitry Antipov <dantipov@cloudlinux.com> (cherry picked from commit af08077fb4c60dee516948ce7bf9bed91de62119)
-rw-r--r--lib/fsm.c14
1 files changed, 8 insertions, 6 deletions
diff --git a/lib/fsm.c b/lib/fsm.c
index 28eb9431b..3d70fbfe0 100644
--- a/lib/fsm.c
+++ b/lib/fsm.c
@@ -313,14 +313,16 @@ static int fsmOpenat(int dirfd, const char *path, int flags, int dir)
*/
if (fd < 0 && errno == ELOOP && flags != sflags) {
int ffd = openat(dirfd, path, flags);
- if (ffd >= 0 && fstatat(dirfd, path, &lsb, AT_SYMLINK_NOFOLLOW) == 0) {
- if (fstat(ffd, &sb) == 0) {
- if (lsb.st_uid == 0 || lsb.st_uid == sb.st_uid) {
- fd = ffd;
- } else {
- close(ffd);
+ if (ffd >= 0) {
+ if (fstatat(dirfd, path, &lsb, AT_SYMLINK_NOFOLLOW) == 0) {
+ if (fstat(ffd, &sb) == 0) {
+ if (lsb.st_uid == 0 || lsb.st_uid == sb.st_uid) {
+ fd = ffd;
+ }
}
}
+ if (ffd != fd)
+ close(ffd);
}
}