Thanks. Pushed.

commit cc2e4db36f25c32a118e2c4b06c719d636c3196f
Author: Jakub Filak <[email protected]>
Date:   Mon Feb 4 09:13:43 2013 +0100

    dd: always sanitize mode of saved file
    
    - we use O_CREAT as the argument for open() and man says:
        'The permissions of the created file are (mode & ~umask)'
    - we want to set the required mode without mangling it by umask, thus we 
have to
      change file's mode by chmod
    - related to trac#927
    
    Signed-off-by: Jakub Filak <[email protected]>

diff --git a/src/lib/dump_dir.c b/src/lib/dump_dir.c
index 37606dd..213236c 100644
--- a/src/lib/dump_dir.c
+++ b/src/lib/dump_dir.c
@@ -893,6 +893,15 @@ static bool save_binary_file(const char *path, const char* 
data, unsigned size,
         }
     }
 
+    /* O_CREATE in the open() call above causes that the permissions of the
+     * created file are (mode & ~umask) */
+    if (fchmod(fd, mode) == -1)
+    {
+        perror_msg("Can't change mode of '%s'", path);
+        close(fd);
+        return false;
+    }
+
     unsigned r = full_write(fd, data, size);
     close(fd);
     if (r != size)


On Friday, February 01, 2013 05:29:15 PM Denys Vlasenko wrote:
> On 02/01/2013 09:17 AM, Jakub Filak wrote:
> > +void dd_sanitize_items_mode_and_owner(struct dump_dir *dd, const char
> > *name)
> I see that you use this function only in one place,
> in "[ABRT PATCH 2/6] dbus: sanitize touched element":
> 
>              dd_save_text(dd, element, value);
> +            dd_sanitize_items_mode_and_owner(dd, element);
> 
> Maybe we should do it inside dd_save_text()?
> For one, we will have a fd and will be able to use fchmod/fchown,
> which aren't vulnerable to symlink attacks.
> 
> dd_save_text() ends up doing this:
> 
> static bool save_binary_file(const char *path, const char* data, unsigned
> size, uid_t uid, gid_t gid, mode_t mode) {
>     /* the mode is set by the caller, see dd_create() for security analysis
> */ unlink(path);
>     int fd = open(path, O_WRONLY | O_TRUNC | O_CREAT | O_NOFOLLOW, mode);
>     if (fd < 0)
>     {
>         perror_msg("Can't open file '%s'", path);
>         return false;
>     }
> 
>     if (uid != (uid_t)-1L)
>     {
>         if (fchown(fd, uid, gid) == -1)
>         {
>             perror_msg("Can't change '%s' ownership to %lu:%lu", path,
> (long)uid, (long)gid); }
>     }
> 
>     unsigned r = full_write(fd, data, size);
>     close(fd);
>     if (r != size)
>     {
>         error_msg("Can't save file '%s'", path);
>         return false;
>     }
> 
>     return true;
> }
> 
> It already does fchown().
> If we'll replace O_TRUNC with O_EXCL, we'd ensure that mode is set correctly
> too (but... umask?); or we can bite the bullet and add fchmod() here.

Reply via email to