summaryrefslogtreecommitdiff
path: root/lib/mkdir-p.c
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2006-12-04 07:23:36 +0000
committerPaul Eggert <eggert@cs.ucla.edu>2006-12-04 07:23:36 +0000
commitd7df32475ce350a132c7c842e192d52780eea129 (patch)
tree5ba3ffaa488028a0a5f28eb9785c434233471829 /lib/mkdir-p.c
parent34bc3595924e9c87130f4b9c9aa349488c82ab7f (diff)
downloadgnulib-d7df32475ce350a132c7c842e192d52780eea129.tar.gz
* lib/mkdir-p.c (make_dir_parents): Fix race condition when making
a directory that is about to be chowned. Such a directory's initial file permissions should permit the owner only and this should not be changed until after the chown, since the group and other bits would be incorrect if they granted permission before the chown.
Diffstat (limited to 'lib/mkdir-p.c')
-rw-r--r--lib/mkdir-p.c15
1 files changed, 12 insertions, 3 deletions
diff --git a/lib/mkdir-p.c b/lib/mkdir-p.c
index 19b962bf0f..a927d5d571 100644
--- a/lib/mkdir-p.c
+++ b/lib/mkdir-p.c
@@ -115,7 +115,14 @@ make_dir_parents (char *dir,
if (0 <= prefix_len)
{
- if (mkdir (dir + prefix_len, mode) == 0)
+ /* If the ownership will change, create the directory with
+ more restrictive permissions at first, so unauthorized
+ users cannot nip in before the directory is ready. */
+ mode_t mkdir_mode = mode;
+ if (! (owner == (uid_t) -1 && group == (gid_t) -1))
+ mkdir_mode &= S_IRWXU;
+
+ if (mkdir (dir + prefix_len, mkdir_mode) == 0)
{
announce (dir, options);
preserve_existing =
@@ -126,7 +133,10 @@ make_dir_parents (char *dir,
| (mode & S_IRUSR ? SAVEWD_CHDIR_READABLE : 0));
}
else
- mkdir_errno = errno;
+ {
+ mkdir_errno = errno;
+ mkdir_mode = -1;
+ }
if (preserve_existing)
{
@@ -163,7 +173,6 @@ make_dir_parents (char *dir,
}
else
{
- mode_t mkdir_mode = (mkdir_errno == 0 ? mode : -1);
char const *subdir = (chdir_ok ? "." : dir + prefix_len);
if (dirchownmod (fd, subdir, mkdir_mode, owner, group,
mode, mode_bits)