btrfs: don't leak opened directory handle
authorNoel Power <noel.power@suse.com>
Tue, 4 Nov 2014 15:52:49 +0000 (16:52 +0100)
committerDavid Disseldorp <ddiss@samba.org>
Tue, 4 Nov 2014 19:51:02 +0000 (20:51 +0100)
Closing a directory handle file descriptor via close() is undefined,
according to:
http://pubs.opengroup.org/onlinepubs/9699919799/functions/dirfd.html

Signed-off-by: Noel Power <noel.power@suse.com>
Reviewed-by: David Disseldorp <ddiss@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
Autobuild-User(master): David Disseldorp <ddiss@samba.org>
Autobuild-Date(master): Tue Nov  4 20:51:02 CET 2014 on sn-devel-104

source3/modules/vfs_btrfs.c

index c1e17b301ec35e132243086540b8382780c8e48c..51442391ce68169dec1a92da50494c4356e3f306 100644 (file)
@@ -245,23 +245,29 @@ static NTSTATUS btrfs_get_compression(struct vfs_handle_struct *handle,
        int fd;
        bool opened = false;
        NTSTATUS status;
+       DIR *dir = NULL;
 
        if ((fsp != NULL) && (fsp->fh->fd != -1)) {
                fd = fsp->fh->fd;
        } else if (smb_fname != NULL) {
                if (S_ISDIR(smb_fname->st.st_ex_mode)) {
-                       DIR *dir = opendir(smb_fname->base_name);
+                       dir = opendir(smb_fname->base_name);
                        if (dir == NULL) {
                                return NT_STATUS_UNSUCCESSFUL;
                        }
+                       opened = true;
                        fd = dirfd(dir);
+                       if (fd < 0) {
+                               status = NT_STATUS_UNSUCCESSFUL;
+                               goto err_close;
+                       }
                } else {
                        fd = open(smb_fname->base_name, O_RDONLY);
+                       if (fd < 0) {
+                               return NT_STATUS_UNSUCCESSFUL;
+                       }
+                       opened = true;
                }
-               if (fd < 0) {
-                       return NT_STATUS_UNSUCCESSFUL;
-               }
-               opened = true;
        } else {
                return NT_STATUS_INVALID_PARAMETER;
        }
@@ -281,7 +287,11 @@ static NTSTATUS btrfs_get_compression(struct vfs_handle_struct *handle,
        status = NT_STATUS_OK;
 err_close:
        if (opened) {
-               close(fd);
+               if (dir != NULL) {
+                       closedir(dir);
+               } else {
+                       close(fd);
+               }
        }
 
        return status;