]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
Handle umask a little more carefully: Instead of setting umask to
authorTim Kientzle <kientzle@gmail.com>
Sat, 30 Oct 2010 07:38:53 +0000 (03:38 -0400)
committerTim Kientzle <kientzle@gmail.com>
Sat, 30 Oct 2010 07:38:53 +0000 (03:38 -0400)
zero, then restoring a file, then restoring umask, just query
the umask and adjust the file restore operations to account for it.

Go ahead and query the umask at new() time as well.
This opens the possibility of removing the umask query from
write_disk_header if you want to make libarchive behave more
nicely with threads.

SVN-Revision: 2768

libarchive/archive_write_disk.c

index 8b86f70de148a1d535d8d400035e454985ad25d6..86db8d753bc22530d52ccf074974cfc4ac7496b1 100644 (file)
@@ -426,15 +426,12 @@ _archive_write_disk_header(struct archive *_a, struct archive_entry *entry)
                return (ret);
 
        /*
-        * Set the umask to zero so we get predictable mode settings.
+        * Query the umask so we get predictable mode settings.
         * This gets done on every call to _write_header in case the
         * user edits their umask during the extraction for some
-        * reason. This will be reset before we return.  Note that we
-        * don't need to do this in _finish_entry, as the chmod(), etc,
-        * system calls don't obey umask.
+        * reason.
         */
-       a->user_umask = umask(0);
-       /* From here on, early exit requires "goto done" to clean up. */
+       umask(a->user_umask = umask(0));
 
        /* Figure out what we need to do for this entry. */
        a->todo = TODO_MODE_BASE;
@@ -493,7 +490,7 @@ _archive_write_disk_header(struct archive *_a, struct archive_entry *entry)
        if (a->flags & ARCHIVE_EXTRACT_SECURE_SYMLINKS) {
                ret = check_symlinks(a);
                if (ret != ARCHIVE_OK)
-                       goto done;
+                       return (ret);
        }
 #if defined(HAVE_FCHDIR) && defined(PATH_MAX)
        /* If path exceeds PATH_MAX, shorten the path. */
@@ -628,9 +625,6 @@ _archive_write_disk_header(struct archive *_a, struct archive_entry *entry)
                archive_entry_set_size(entry, 0);
                a->filesize = 0;
        }
-done:
-       /* Restore the user's umask before returning. */
-       umask(a->user_umask);
 
        return (ret);
 }
@@ -988,6 +982,8 @@ archive_write_disk_new(void)
        a->lookup_uid = trivial_lookup_uid;
        a->lookup_gid = trivial_lookup_gid;
        a->start_time = time(NULL);
+       /* Query and restore the umask. */
+       umask(a->user_umask = umask(0));
 #ifdef HAVE_GETEUID
        a->user_uid = geteuid();
 #endif /* HAVE_GETEUID */
@@ -1275,7 +1271,7 @@ create_filesystem_object(struct archive_write_disk *a)
         * that SUID, SGID, etc, require additional work to ensure
         * security, so we never restore them at this point.
         */
-       mode = final_mode & 0777;
+       mode = final_mode & 0777 & a->user_umask;
 
        switch (a->mode & AE_IFMT) {
        default: