bug-gzip
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Minor security issue in copying permission bits


From: Lasse Collin
Subject: Minor security issue in copying permission bits
Date: Tue, 6 Nov 2007 22:13:53 +0200
User-agent: KMail/1.9.6

In some rare situations the output file may be accessible by users who 
didn't have permissions to access the input file. This is due to how 
gzip copies UID, GID, and permissions.

An example should clarify the issue. First the root user creates a file:

    # echo foo > foo
    # chgrp restrict foo
    # chmod 606 foo
    # ls -l foo
    -rw----rw- 1 root restrict 4 2007-11-06 12:34 foo.gz

User who isn't in the "restrict" group compresses the file:

    $ gzip foo
    $ ls -l foo.gz
    -rw----rw- 1 barney users 4 2007-11-06 12:34 foo.gz

Now the users in the "restrict" group will have access to foo.gz 
although they didn't have access to the original foo file.

This issue applies to bzip2 1.0.4 and LZMA Utils 4.32.x too. Below is a 
patch against gzip 1.3.12. I would like to hear if the patch is good, 
so I can report the issue to upstream of bzip2 and permanently fix it 
in LZMA Utils.

diff -ru gzip-1.3.12.orig/gzip.c gzip-1.3.12/gzip.c
--- gzip-1.3.12.orig/gzip.c     2007-03-20 07:09:51.000000000 +0200
+++ gzip-1.3.12/gzip.c  2007-11-06 21:07:37.860644323 +0200
@@ -1650,14 +1650,32 @@
 #endif
 
 #ifndef NO_CHOWN
+    /* Copy ownership */
 # if HAVE_FCHOWN
-    fchown (ofd, ifstat->st_uid, ifstat->st_gid);  /* Copy ownership */
+    (void) fchown (ofd, ifstat->st_uid, -1);
+    r = fchown (ofd, -1, ifstat->st_gid);
 # elif HAVE_CHOWN
-    chown(ofname, ifstat->st_uid, ifstat->st_gid);  /* Copy ownership */
+    (void) chown (ofname, ifstat->st_uid, -1);
+    r = chown (ofname, -1, ifstat->st_gid);
 # endif
+#else
+    r = 0;
 #endif
 
     /* Copy the protection modes */
+    if (r != 0) {
+        /* Setting the GID of the file failed. We can still safely
+         * copy some permissions: `group' must be at least as strict
+         * as `other' and also vice versa.
+         *
+         * NOTE: After this, the owner of the source file may get
+         * additional permissions. This shouldn't be too bad, because
+         * the owner would have had permission to chmod the original
+         * file anyway.
+         */
+        mode_t tmp = ((mode & 0070) >> 3) & (mode & 0007);
+        mode = (mode & 0700) | (tmp << 3) | tmp;
+    }
 #if HAVE_FCHMOD
     r = fchmod (ofd, mode);
 #else

-- 
Lasse Collin  |  IRC: Larhzu @ IRCnet & Freenode




reply via email to

[Prev in Thread] Current Thread [Next in Thread]