Skip to content

Commit

Permalink
Fix race condition in rpmioMkpath
Browse files Browse the repository at this point in the history
The previous implementation did stat the directory and created it if not
there. This allowed for a race condition where other rpm instances could
create the directory inbetween. This was observed in the wild for
%{_tmppath}.

Do create the directory unconditionally and if that fails see if the
directory is there already.

Not adding a test case as rpmioMkpath is heavily used all over the the
code base and tests for race conditions don't really fit in the test suite.

Resolves: rpm-software-management#3508
  • Loading branch information
ffesti committed Jan 8, 2025
1 parent ed6beb5 commit 1ad1f9b
Showing 1 changed file with 10 additions and 8 deletions.
18 changes: 10 additions & 8 deletions rpmio/rpmfileutil.cc
Original file line number Diff line number Diff line change
Expand Up @@ -122,22 +122,24 @@ int rpmioMkpath(const char * path, mode_t mode, uid_t uid, gid_t gid)
for (;(de=strchr(de+1,'/'));) {
struct stat st;
*de = '\0';
rc = stat(d, &st);
if (rc) {
if (errno != ENOENT)
goto exit;
rc = mkdir(d, mode);
rc = mkdir(d, mode);
if (rc && errno == EEXIST) {
rc = stat(d, &st);
if (rc)
goto exit;
if (!S_ISDIR(st.st_mode)) {
rc = ENOTDIR;
goto exit;
}
} else if (rc) {
goto exit;
} else {
rpmlog(RPMLOG_DEBUG, "created directory(s) %s mode 0%o\n", path, mode);
if (!(uid == (uid_t) -1 && gid == (gid_t) -1)) {
rc = chown(d, uid, gid);
if (rc)
goto exit;
}
} else if (!S_ISDIR(st.st_mode)) {
rc = ENOTDIR;
goto exit;
}
*de = '/';
}
Expand Down

0 comments on commit 1ad1f9b

Please sign in to comment.