From 0f2eb11c4bab0b441cebbba091adbc46d0f79382 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=BCnther=20Deschner?= Date: Wed, 10 Oct 2018 17:32:25 +0200 Subject: [PATCH] s3-vfs: Prevent NULL pointer dereference in vfs_glusterfs. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BUG: https://bugzilla.samba.org/show_bug.cgi?id=13708 Guenther Signed-off-by: Guenther Deschner Reviewed-by: Ralph Boehme Autobuild-User(master): Günther Deschner Autobuild-Date(master): Tue Dec 11 17:26:31 CET 2018 on sn-devel-144 (cherry picked from commit 75d15484f3b71b1a2684c4a73e53aaa467f9932b) --- source3/modules/vfs_glusterfs.c | 200 +++++++++++++++++++++++++++----- 1 file changed, 168 insertions(+), 32 deletions(-) diff --git a/source3/modules/vfs_glusterfs.c b/source3/modules/vfs_glusterfs.c index 38abb78f1f3..e6448cc874a 100644 --- a/source3/modules/vfs_glusterfs.c +++ b/source3/modules/vfs_glusterfs.c @@ -491,11 +491,33 @@ static DIR *vfs_gluster_opendir(struct vfs_handle_struct *handle, return (DIR *) fd; } +static glfs_fd_t *vfs_gluster_fetch_glfd(struct vfs_handle_struct *handle, + files_struct *fsp) +{ + glfs_fd_t **glfd = (glfs_fd_t **)VFS_FETCH_FSP_EXTENSION(handle, fsp); + if (glfd == NULL) { + DBG_INFO("Failed to fetch fsp extension\n"); + return NULL; + } + if (*glfd == NULL) { + DBG_INFO("Empty glfs_fd_t pointer\n"); + return NULL; + } + + return *glfd; +} + static DIR *vfs_gluster_fdopendir(struct vfs_handle_struct *handle, files_struct *fsp, const char *mask, uint32_t attributes) { - return (DIR *) *(glfs_fd_t **)VFS_FETCH_FSP_EXTENSION(handle, fsp); + glfs_fd_t *glfd = vfs_gluster_fetch_glfd(handle, fsp); + if (glfd == NULL) { + DBG_ERR("Failed to fetch gluster fd\n"); + return NULL; + } + + return (DIR *)glfd; } static int vfs_gluster_closedir(struct vfs_handle_struct *handle, DIR *dirp) @@ -586,8 +608,12 @@ static int vfs_gluster_open(struct vfs_handle_struct *handle, static int vfs_gluster_close(struct vfs_handle_struct *handle, files_struct *fsp) { - glfs_fd_t *glfd; - glfd = *(glfs_fd_t **)VFS_FETCH_FSP_EXTENSION(handle, fsp); + glfs_fd_t *glfd = vfs_gluster_fetch_glfd(handle, fsp); + if (glfd == NULL) { + DBG_ERR("Failed to fetch gluster fd\n"); + return -1; + } + VFS_REMOVE_FSP_EXTENSION(handle, fsp); return glfs_close(glfd); } @@ -595,14 +621,26 @@ static int vfs_gluster_close(struct vfs_handle_struct *handle, static ssize_t vfs_gluster_read(struct vfs_handle_struct *handle, files_struct *fsp, void *data, size_t n) { - return glfs_read(*(glfs_fd_t **)VFS_FETCH_FSP_EXTENSION(handle, fsp), data, n, 0); + glfs_fd_t *glfd = vfs_gluster_fetch_glfd(handle, fsp); + if (glfd == NULL) { + DBG_ERR("Failed to fetch gluster fd\n"); + return -1; + } + + return glfs_read(glfd, data, n, 0); } static ssize_t vfs_gluster_pread(struct vfs_handle_struct *handle, files_struct *fsp, void *data, size_t n, off_t offset) { - return glfs_pread(*(glfs_fd_t **)VFS_FETCH_FSP_EXTENSION(handle, fsp), data, n, offset, 0); + glfs_fd_t *glfd = vfs_gluster_fetch_glfd(handle, fsp); + if (glfd == NULL) { + DBG_ERR("Failed to fetch gluster fd\n"); + return -1; + } + + return glfs_pread(glfd, data, n, offset, 0); } struct glusterfs_aio_state; @@ -795,6 +833,12 @@ static struct tevent_req *vfs_gluster_pread_send(struct vfs_handle_struct struct glusterfs_aio_state *state = NULL; struct tevent_req *req = NULL; int ret = 0; + glfs_fd_t *glfd = vfs_gluster_fetch_glfd(handle, fsp); + + if (glfd == NULL) { + DBG_ERR("Failed to fetch gluster fd\n"); + return NULL; + } state = aio_state_create(mem_ctx); @@ -810,8 +854,7 @@ static struct tevent_req *vfs_gluster_pread_send(struct vfs_handle_struct } PROFILE_TIMESTAMP(&state->start); - ret = glfs_pread_async(*(glfs_fd_t **)VFS_FETCH_FSP_EXTENSION(handle, - fsp), data, n, offset, 0, aio_glusterfs_done, + ret = glfs_pread_async(glfd, data, n, offset, 0, aio_glusterfs_done, state); if (ret < 0) { tevent_req_error(req, -ret); @@ -831,6 +874,12 @@ static struct tevent_req *vfs_gluster_pwrite_send(struct vfs_handle_struct struct glusterfs_aio_state *state = NULL; struct tevent_req *req = NULL; int ret = 0; + glfs_fd_t *glfd = vfs_gluster_fetch_glfd(handle, fsp); + + if (glfd == NULL) { + DBG_ERR("Failed to fetch gluster fd\n"); + return NULL; + } state = aio_state_create(mem_ctx); @@ -846,8 +895,7 @@ static struct tevent_req *vfs_gluster_pwrite_send(struct vfs_handle_struct } PROFILE_TIMESTAMP(&state->start); - ret = glfs_pwrite_async(*(glfs_fd_t **)VFS_FETCH_FSP_EXTENSION(handle, - fsp), data, n, offset, 0, aio_glusterfs_done, + ret = glfs_pwrite_async(glfd, data, n, offset, 0, aio_glusterfs_done, state); if (ret < 0) { tevent_req_error(req, -ret); @@ -890,20 +938,38 @@ static ssize_t vfs_gluster_recv(struct tevent_req *req, static ssize_t vfs_gluster_write(struct vfs_handle_struct *handle, files_struct *fsp, const void *data, size_t n) { - return glfs_write(*(glfs_fd_t **)VFS_FETCH_FSP_EXTENSION(handle, fsp), data, n, 0); + glfs_fd_t *glfd = vfs_gluster_fetch_glfd(handle, fsp); + if (glfd == NULL) { + DBG_ERR("Failed to fetch gluster fd\n"); + return -1; + } + + return glfs_write(glfd, data, n, 0); } static ssize_t vfs_gluster_pwrite(struct vfs_handle_struct *handle, files_struct *fsp, const void *data, size_t n, off_t offset) { - return glfs_pwrite(*(glfs_fd_t **)VFS_FETCH_FSP_EXTENSION(handle, fsp), data, n, offset, 0); + glfs_fd_t *glfd = vfs_gluster_fetch_glfd(handle, fsp); + if (glfd == NULL) { + DBG_ERR("Failed to fetch gluster fd\n"); + return -1; + } + + return glfs_pwrite(glfd, data, n, offset, 0); } static off_t vfs_gluster_lseek(struct vfs_handle_struct *handle, files_struct *fsp, off_t offset, int whence) { - return glfs_lseek(*(glfs_fd_t **)VFS_FETCH_FSP_EXTENSION(handle, fsp), offset, whence); + glfs_fd_t *glfd = vfs_gluster_fetch_glfd(handle, fsp); + if (glfd == NULL) { + DBG_ERR("Failed to fetch gluster fd\n"); + return -1; + } + + return glfs_lseek(glfd, offset, whence); } static ssize_t vfs_gluster_sendfile(struct vfs_handle_struct *handle, int tofd, @@ -934,7 +1000,13 @@ static int vfs_gluster_rename(struct vfs_handle_struct *handle, static int vfs_gluster_fsync(struct vfs_handle_struct *handle, files_struct *fsp) { - return glfs_fsync(*(glfs_fd_t **)VFS_FETCH_FSP_EXTENSION(handle, fsp)); + glfs_fd_t *glfd = vfs_gluster_fetch_glfd(handle, fsp); + if (glfd == NULL) { + DBG_ERR("Failed to fetch gluster fd\n"); + return -1; + } + + return glfs_fsync(glfd); } static struct tevent_req *vfs_gluster_fsync_send(struct vfs_handle_struct @@ -945,6 +1017,12 @@ static struct tevent_req *vfs_gluster_fsync_send(struct vfs_handle_struct struct tevent_req *req = NULL; struct glusterfs_aio_state *state = NULL; int ret = 0; + glfs_fd_t *glfd = vfs_gluster_fetch_glfd(handle, fsp); + + if (glfd == NULL) { + DBG_ERR("Failed to fetch gluster fd\n"); + return NULL; + } state = aio_state_create(mem_ctx); @@ -960,8 +1038,7 @@ static struct tevent_req *vfs_gluster_fsync_send(struct vfs_handle_struct } PROFILE_TIMESTAMP(&state->start); - ret = glfs_fsync_async(*(glfs_fd_t **)VFS_FETCH_FSP_EXTENSION(handle, - fsp), aio_glusterfs_done, state); + ret = glfs_fsync_async(glfd, aio_glusterfs_done, state); if (ret < 0) { tevent_req_error(req, -ret); return tevent_req_post(req, ev); @@ -1000,8 +1077,14 @@ static int vfs_gluster_fstat(struct vfs_handle_struct *handle, { struct stat st; int ret; + glfs_fd_t *glfd = vfs_gluster_fetch_glfd(handle, fsp); - ret = glfs_fstat(*(glfs_fd_t **)VFS_FETCH_FSP_EXTENSION(handle, fsp), &st); + if (glfd == NULL) { + DBG_ERR("Failed to fetch gluster fd\n"); + return -1; + } + + ret = glfs_fstat(glfd, &st); if (ret == 0) { smb_stat_ex_from_stat(sbuf, &st); } @@ -1052,7 +1135,14 @@ static int vfs_gluster_chmod(struct vfs_handle_struct *handle, static int vfs_gluster_fchmod(struct vfs_handle_struct *handle, files_struct *fsp, mode_t mode) { - return glfs_fchmod(*(glfs_fd_t **)VFS_FETCH_FSP_EXTENSION(handle, fsp), mode); + glfs_fd_t *glfd = vfs_gluster_fetch_glfd(handle, fsp); + + if (glfd == NULL) { + DBG_ERR("Failed to fetch gluster fd\n"); + return -1; + } + + return glfs_fchmod(glfd, mode); } static int vfs_gluster_chown(struct vfs_handle_struct *handle, @@ -1066,7 +1156,13 @@ static int vfs_gluster_chown(struct vfs_handle_struct *handle, static int vfs_gluster_fchown(struct vfs_handle_struct *handle, files_struct *fsp, uid_t uid, gid_t gid) { - return glfs_fchown(*(glfs_fd_t **)VFS_FETCH_FSP_EXTENSION(handle, fsp), uid, gid); + glfs_fd_t *glfd = vfs_gluster_fetch_glfd(handle, fsp); + if (glfd == NULL) { + DBG_ERR("Failed to fetch gluster fd\n"); + return -1; + } + + return glfs_fchown(glfd, uid, gid); } static int vfs_gluster_lchown(struct vfs_handle_struct *handle, @@ -1144,7 +1240,13 @@ static int vfs_gluster_ntimes(struct vfs_handle_struct *handle, static int vfs_gluster_ftruncate(struct vfs_handle_struct *handle, files_struct *fsp, off_t offset) { - return glfs_ftruncate(*(glfs_fd_t **)VFS_FETCH_FSP_EXTENSION(handle, fsp), offset); + glfs_fd_t *glfd = vfs_gluster_fetch_glfd(handle, fsp); + if (glfd == NULL) { + DBG_ERR("Failed to fetch gluster fd\n"); + return -1; + } + + return glfs_ftruncate(glfd, offset); } static int vfs_gluster_fallocate(struct vfs_handle_struct *handle, @@ -1154,6 +1256,11 @@ static int vfs_gluster_fallocate(struct vfs_handle_struct *handle, { #ifdef HAVE_GFAPI_VER_6 int keep_size, punch_hole; + glfs_fd_t *glfd = vfs_gluster_fetch_glfd(handle, fsp); + if (glfd == NULL) { + DBG_ERR("Failed to fetch gluster fd\n"); + return -1; + } keep_size = mode & VFS_FALLOCATE_FL_KEEP_SIZE; punch_hole = mode & VFS_FALLOCATE_FL_PUNCH_HOLE; @@ -1165,14 +1272,10 @@ static int vfs_gluster_fallocate(struct vfs_handle_struct *handle, } if (punch_hole) { - return glfs_discard(*(glfs_fd_t **) - VFS_FETCH_FSP_EXTENSION(handle, fsp), - offset, len); + return glfs_discard(glfd, offset, len); } - return glfs_fallocate(*(glfs_fd_t **) - VFS_FETCH_FSP_EXTENSION(handle, fsp), - keep_size, offset, len); + return glfs_fallocate(glfd, keep_size, offset, len); #else errno = ENOTSUP; return -1; @@ -1209,6 +1312,11 @@ static bool vfs_gluster_lock(struct vfs_handle_struct *handle, { struct flock flock = { 0, }; int ret; + glfs_fd_t *glfd = vfs_gluster_fetch_glfd(handle, fsp); + if (glfd == NULL) { + DBG_ERR("Failed to fetch gluster fd\n"); + return false; + } flock.l_type = type; flock.l_whence = SEEK_SET; @@ -1216,7 +1324,7 @@ static bool vfs_gluster_lock(struct vfs_handle_struct *handle, flock.l_len = count; flock.l_pid = 0; - ret = glfs_posix_lock(*(glfs_fd_t **)VFS_FETCH_FSP_EXTENSION(handle, fsp), op, &flock); + ret = glfs_posix_lock(glfd, op, &flock); if (op == F_GETLK) { /* lock query, true if someone else has locked */ @@ -1256,6 +1364,11 @@ static bool vfs_gluster_getlock(struct vfs_handle_struct *handle, { struct flock flock = { 0, }; int ret; + glfs_fd_t *glfd = vfs_gluster_fetch_glfd(handle, fsp); + if (glfd == NULL) { + DBG_ERR("Failed to fetch gluster fd\n"); + return false; + } flock.l_type = *ptype; flock.l_whence = SEEK_SET; @@ -1263,7 +1376,7 @@ static bool vfs_gluster_getlock(struct vfs_handle_struct *handle, flock.l_len = *pcount; flock.l_pid = 0; - ret = glfs_posix_lock(*(glfs_fd_t **)VFS_FETCH_FSP_EXTENSION(handle, fsp), F_GETLK, &flock); + ret = glfs_posix_lock(glfd, F_GETLK, &flock); if (ret == -1) { return false; @@ -1373,7 +1486,13 @@ static ssize_t vfs_gluster_fgetxattr(struct vfs_handle_struct *handle, files_struct *fsp, const char *name, void *value, size_t size) { - return glfs_fgetxattr(*(glfs_fd_t **)VFS_FETCH_FSP_EXTENSION(handle, fsp), name, value, size); + glfs_fd_t *glfd = vfs_gluster_fetch_glfd(handle, fsp); + if (glfd == NULL) { + DBG_ERR("Failed to fetch gluster fd\n"); + return -1; + } + + return glfs_fgetxattr(glfd, name, value, size); } static ssize_t vfs_gluster_listxattr(struct vfs_handle_struct *handle, @@ -1388,7 +1507,13 @@ static ssize_t vfs_gluster_flistxattr(struct vfs_handle_struct *handle, files_struct *fsp, char *list, size_t size) { - return glfs_flistxattr(*(glfs_fd_t **)VFS_FETCH_FSP_EXTENSION(handle, fsp), list, size); + glfs_fd_t *glfd = vfs_gluster_fetch_glfd(handle, fsp); + if (glfd == NULL) { + DBG_ERR("Failed to fetch gluster fd\n"); + return -1; + } + + return glfs_flistxattr(glfd, list, size); } static int vfs_gluster_removexattr(struct vfs_handle_struct *handle, @@ -1401,7 +1526,13 @@ static int vfs_gluster_removexattr(struct vfs_handle_struct *handle, static int vfs_gluster_fremovexattr(struct vfs_handle_struct *handle, files_struct *fsp, const char *name) { - return glfs_fremovexattr(*(glfs_fd_t **)VFS_FETCH_FSP_EXTENSION(handle, fsp), name); + glfs_fd_t *glfd = vfs_gluster_fetch_glfd(handle, fsp); + if (glfd == NULL) { + DBG_ERR("Failed to fetch gluster fd\n"); + return -1; + } + + return glfs_fremovexattr(glfd, name); } static int vfs_gluster_setxattr(struct vfs_handle_struct *handle, @@ -1416,8 +1547,13 @@ static int vfs_gluster_fsetxattr(struct vfs_handle_struct *handle, files_struct *fsp, const char *name, const void *value, size_t size, int flags) { - return glfs_fsetxattr(*(glfs_fd_t **)VFS_FETCH_FSP_EXTENSION(handle, fsp), name, value, size, - flags); + glfs_fd_t *glfd = vfs_gluster_fetch_glfd(handle, fsp); + if (glfd == NULL) { + DBG_ERR("Failed to fetch gluster fd\n"); + return -1; + } + + return glfs_fsetxattr(glfd, name, value, size, flags); } /* AIO Operations */ -- 2.19.2