Univention Bugzilla – Attachment 8496 Details for
Bug 43679
Samba: Multiple issues (3.3)
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
4.4-racefix.diff
4.4-racefix.diff (text/plain), 21.70 KB, created by
Arvid Requate
on 2017-03-06 21:13 CET
(
hide
)
Description:
4.4-racefix.diff
Filename:
MIME Type:
Creator:
Arvid Requate
Created:
2017-03-06 21:13 CET
Size:
21.70 KB
patch
obsolete
>From c903ca6a227cd190b270c52ac3a84ad2148c9651 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Mon, 19 Dec 2016 11:55:56 -0800 >Subject: [PATCH 01/11] s3: smbd: Create wrapper function for OpenDir in > preparation for making robust. > >CVE-2017-2619 > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 > >Signed-off-by: Jeremy Allison <jra@samba.org> >--- > source3/smbd/dir.c | 15 ++++++++++++++- > 1 file changed, 14 insertions(+), 1 deletion(-) > >diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c >index 3805915..cbd32e3 100644 >--- a/source3/smbd/dir.c >+++ b/source3/smbd/dir.c >@@ -1588,7 +1588,8 @@ static int smb_Dir_destructor(struct smb_Dir *dirp) > Open a directory. > ********************************************************************/ > >-struct smb_Dir *OpenDir(TALLOC_CTX *mem_ctx, connection_struct *conn, >+static struct smb_Dir *OpenDir_internal(TALLOC_CTX *mem_ctx, >+ connection_struct *conn, > const char *name, > const char *mask, > uint32_t attr) >@@ -1628,6 +1629,18 @@ struct smb_Dir *OpenDir(TALLOC_CTX *mem_ctx, connection_struct *conn, > return NULL; > } > >+struct smb_Dir *OpenDir(TALLOC_CTX *mem_ctx, connection_struct *conn, >+ const char *name, >+ const char *mask, >+ uint32_t attr) >+{ >+ return OpenDir_internal(mem_ctx, >+ conn, >+ name, >+ mask, >+ attr); >+} >+ > /******************************************************************* > Open a directory from an fsp. > ********************************************************************/ >-- >2.9.3 > > >From ef03034fd0b89f64983444d662ff16d8fe2f2f0b Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Mon, 19 Dec 2016 16:25:26 -0800 >Subject: [PATCH 02/11] s3: smbd: Opendir_internal() early return if > SMB_VFS_OPENDIR failed. > >CVE-2017-2619 > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 > >Signed-off-by: Jeremy Allison <jra@samba.org> >--- > source3/smbd/dir.c | 16 ++++++++-------- > 1 file changed, 8 insertions(+), 8 deletions(-) > >diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c >index cbd32e3..ea4b301 100644 >--- a/source3/smbd/dir.c >+++ b/source3/smbd/dir.c >@@ -1601,20 +1601,12 @@ static struct smb_Dir *OpenDir_internal(TALLOC_CTX *mem_ctx, > return NULL; > } > >- dirp->conn = conn; >- dirp->name_cache_size = lp_directory_name_cache_size(SNUM(conn)); >- > dirp->dir_path = talloc_strdup(dirp, name); > if (!dirp->dir_path) { > errno = ENOMEM; > goto fail; > } > >- if (sconn && !sconn->using_smb2) { >- sconn->searches.dirhandles_open++; >- } >- talloc_set_destructor(dirp, smb_Dir_destructor); >- > dirp->dir = SMB_VFS_OPENDIR(conn, dirp->dir_path, mask, attr); > if (!dirp->dir) { > DEBUG(5,("OpenDir: Can't open %s. %s\n", dirp->dir_path, >@@ -1622,6 +1614,14 @@ static struct smb_Dir *OpenDir_internal(TALLOC_CTX *mem_ctx, > goto fail; > } > >+ dirp->conn = conn; >+ dirp->name_cache_size = lp_directory_name_cache_size(SNUM(conn)); >+ >+ if (sconn && !sconn->using_smb2) { >+ sconn->searches.dirhandles_open++; >+ } >+ talloc_set_destructor(dirp, smb_Dir_destructor); >+ > return dirp; > > fail: >-- >2.9.3 > > >From 0c3c22f38b0864e9894647aad1a4bc0241b9f4ae Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Mon, 19 Dec 2016 16:35:00 -0800 >Subject: [PATCH 03/11] s3: smbd: Create and use open_dir_safely(). Use from > OpenDir(). > >Hardens OpenDir against TOC/TOU races. > >CVE-2017-2619 > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 > >Signed-off-by: Jeremy Allison <jra@samba.org> >--- > source3/smbd/dir.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++------- > 1 file changed, 61 insertions(+), 9 deletions(-) > >diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c >index ea4b301..39a6e67 100644 >--- a/source3/smbd/dir.c >+++ b/source3/smbd/dir.c >@@ -1601,15 +1601,9 @@ static struct smb_Dir *OpenDir_internal(TALLOC_CTX *mem_ctx, > return NULL; > } > >- dirp->dir_path = talloc_strdup(dirp, name); >- if (!dirp->dir_path) { >- errno = ENOMEM; >- goto fail; >- } >- >- dirp->dir = SMB_VFS_OPENDIR(conn, dirp->dir_path, mask, attr); >+ dirp->dir = SMB_VFS_OPENDIR(conn, name, mask, attr); > if (!dirp->dir) { >- DEBUG(5,("OpenDir: Can't open %s. %s\n", dirp->dir_path, >+ DEBUG(5,("OpenDir: Can't open %s. %s\n", name, > strerror(errno) )); > goto fail; > } >@@ -1629,12 +1623,70 @@ static struct smb_Dir *OpenDir_internal(TALLOC_CTX *mem_ctx, > return NULL; > } > >+/**************************************************************************** >+ Open a directory handle by pathname, ensuring it's under the share path. >+****************************************************************************/ >+ >+static struct smb_Dir *open_dir_safely(TALLOC_CTX *ctx, >+ connection_struct *conn, >+ const char *name, >+ const char *wcard, >+ uint32_t attr) >+{ >+ struct smb_Dir *dir_hnd = NULL; >+ char *saved_dir = vfs_GetWd(ctx, conn); >+ NTSTATUS status; >+ >+ if (saved_dir == NULL) { >+ return NULL; >+ } >+ >+ if (vfs_ChDir(conn, name) == -1) { >+ goto out; >+ } >+ >+ /* >+ * Now the directory is pinned, use >+ * REALPATH to ensure we can access it. >+ */ >+ status = check_name(conn, "."); >+ if (!NT_STATUS_IS_OK(status)) { >+ goto out; >+ } >+ >+ dir_hnd = OpenDir_internal(ctx, >+ conn, >+ ".", >+ wcard, >+ attr); >+ >+ if (dir_hnd == NULL) { >+ goto out; >+ } >+ >+ /* >+ * OpenDir_internal only gets "." as the dir name. >+ * Store the real dir name here. >+ */ >+ >+ dir_hnd->dir_path = talloc_strdup(dir_hnd, name); >+ if (!dir_hnd->dir_path) { >+ errno = ENOMEM; >+ } >+ >+ out: >+ >+ vfs_ChDir(conn, saved_dir); >+ TALLOC_FREE(saved_dir); >+ return dir_hnd; >+} >+ > struct smb_Dir *OpenDir(TALLOC_CTX *mem_ctx, connection_struct *conn, > const char *name, > const char *mask, > uint32_t attr) > { >- return OpenDir_internal(mem_ctx, >+ return open_dir_safely(mem_ctx, > conn, > name, > mask, >-- >2.9.3 > > >From 39589a2b7de5768cc515bce58dd243d711e58fd3 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Mon, 19 Dec 2016 12:13:20 -0800 >Subject: [PATCH 04/11] s3: smbd: OpenDir_fsp() use early returns. > >CVE-2017-2619 > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 > >Signed-off-by: Jeremy Allison <jra@samba.org> >--- > source3/smbd/dir.c | 34 +++++++++++++++++++++------------- > 1 file changed, 21 insertions(+), 13 deletions(-) > >diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c >index 39a6e67..ea4f1ab 100644 >--- a/source3/smbd/dir.c >+++ b/source3/smbd/dir.c >@@ -1706,7 +1706,17 @@ static struct smb_Dir *OpenDir_fsp(TALLOC_CTX *mem_ctx, connection_struct *conn, > struct smbd_server_connection *sconn = conn->sconn; > > if (!dirp) { >- return NULL; >+ goto fail; >+ } >+ >+ if (!fsp->is_directory) { >+ errno = EBADF; >+ goto fail; >+ } >+ >+ if (fsp->fh->fd == -1) { >+ errno = EBADF; >+ goto fail; > } > > dirp->conn = conn; >@@ -1723,18 +1733,16 @@ static struct smb_Dir *OpenDir_fsp(TALLOC_CTX *mem_ctx, connection_struct *conn, > } > talloc_set_destructor(dirp, smb_Dir_destructor); > >- if (fsp->is_directory && fsp->fh->fd != -1) { >- dirp->dir = SMB_VFS_FDOPENDIR(fsp, mask, attr); >- if (dirp->dir != NULL) { >- dirp->fsp = fsp; >- } else { >- DEBUG(10,("OpenDir_fsp: SMB_VFS_FDOPENDIR on %s returned " >- "NULL (%s)\n", >- dirp->dir_path, >- strerror(errno))); >- if (errno != ENOSYS) { >- return NULL; >- } >+ dirp->dir = SMB_VFS_FDOPENDIR(fsp, mask, attr); >+ if (dirp->dir != NULL) { >+ dirp->fsp = fsp; >+ } else { >+ DEBUG(10,("OpenDir_fsp: SMB_VFS_FDOPENDIR on %s returned " >+ "NULL (%s)\n", >+ dirp->dir_path, >+ strerror(errno))); >+ if (errno != ENOSYS) { >+ return NULL; > } > } > >-- >2.9.3 > > >From 031ba3f1427d97c48e9911dc98a125661d9088ee Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Mon, 19 Dec 2016 12:15:59 -0800 >Subject: [PATCH 05/11] s3: smbd: OpenDir_fsp() - Fix memory leak on error. > >CVE-2017-2619 > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 > >Signed-off-by: Jeremy Allison <jra@samba.org> >--- > source3/smbd/dir.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > >diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c >index ea4f1ab..b8034be 100644 >--- a/source3/smbd/dir.c >+++ b/source3/smbd/dir.c >@@ -1742,7 +1742,7 @@ static struct smb_Dir *OpenDir_fsp(TALLOC_CTX *mem_ctx, connection_struct *conn, > dirp->dir_path, > strerror(errno))); > if (errno != ENOSYS) { >- return NULL; >+ goto fail; > } > } > >-- >2.9.3 > > >From 54d9bb3aa5b14e51bb1a2fe60ec20bc1cdad373f Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Mon, 19 Dec 2016 12:32:07 -0800 >Subject: [PATCH 06/11] s3: smbd: Move the reference counting and destructor > setup to just before retuning success. > >CVE-2017-2619 > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 > >Signed-off-by: Jeremy Allison <jra@samba.org> >--- > source3/smbd/dir.c | 10 +++++----- > 1 file changed, 5 insertions(+), 5 deletions(-) > >diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c >index b8034be..6b62f14 100644 >--- a/source3/smbd/dir.c >+++ b/source3/smbd/dir.c >@@ -1728,11 +1728,6 @@ static struct smb_Dir *OpenDir_fsp(TALLOC_CTX *mem_ctx, connection_struct *conn, > goto fail; > } > >- if (sconn && !sconn->using_smb2) { >- sconn->searches.dirhandles_open++; >- } >- talloc_set_destructor(dirp, smb_Dir_destructor); >- > dirp->dir = SMB_VFS_FDOPENDIR(fsp, mask, attr); > if (dirp->dir != NULL) { > dirp->fsp = fsp; >@@ -1757,6 +1752,11 @@ static struct smb_Dir *OpenDir_fsp(TALLOC_CTX *mem_ctx, connection_struct *conn, > goto fail; > } > >+ if (sconn && !sconn->using_smb2) { >+ sconn->searches.dirhandles_open++; >+ } >+ talloc_set_destructor(dirp, smb_Dir_destructor); >+ > return dirp; > > fail: >-- >2.9.3 > > >From 1265c298699e0b3a3000e70e07d815c459ff461e Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Mon, 19 Dec 2016 12:35:32 -0800 >Subject: [PATCH 07/11] s3: smbd: Correctly fallback to open_dir_safely if > FDOPENDIR not supported on system. > >CVE-2017-2619 > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 > >Signed-off-by: Jeremy Allison <jra@samba.org> >--- > source3/smbd/dir.c | 15 +++++++-------- > 1 file changed, 7 insertions(+), 8 deletions(-) > >diff --git a/source3/smbd/dir.c b/source3/smbd/dir.c >index 6b62f14..3432788 100644 >--- a/source3/smbd/dir.c >+++ b/source3/smbd/dir.c >@@ -1742,14 +1742,13 @@ static struct smb_Dir *OpenDir_fsp(TALLOC_CTX *mem_ctx, connection_struct *conn, > } > > if (dirp->dir == NULL) { >- /* FDOPENDIR didn't work. Use OPENDIR instead. */ >- dirp->dir = SMB_VFS_OPENDIR(conn, dirp->dir_path, mask, attr); >- } >- >- if (!dirp->dir) { >- DEBUG(5,("OpenDir_fsp: Can't open %s. %s\n", dirp->dir_path, >- strerror(errno) )); >- goto fail; >+ /* FDOPENDIR is not supported. Use OPENDIR instead. */ >+ TALLOC_FREE(dirp); >+ return open_dir_safely(mem_ctx, >+ conn, >+ fsp->fsp_name->base_name, >+ mask, >+ attr); > } > > if (sconn && !sconn->using_smb2) { >-- >2.9.3 > > >From 1c0a1c566a9a43c9c81d42e48b85109a34a486dd Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Thu, 15 Dec 2016 12:52:13 -0800 >Subject: [PATCH 08/11] s3: smbd: Remove O_NOFOLLOW guards. We insist on > O_NOFOLLOW existing. > >CVE-2017-2619 > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 > >Signed-off-by: Jeremy Allison <jra@samba.org> >--- > source3/smbd/open.c | 6 +----- > 1 file changed, 1 insertion(+), 5 deletions(-) > >diff --git a/source3/smbd/open.c b/source3/smbd/open.c >index 25cf417..03a994a 100644 >--- a/source3/smbd/open.c >+++ b/source3/smbd/open.c >@@ -356,8 +356,7 @@ NTSTATUS fd_open(struct connection_struct *conn, > struct smb_filename *smb_fname = fsp->fsp_name; > NTSTATUS status = NT_STATUS_OK; > >-#ifdef O_NOFOLLOW >- /* >+ /* > * Never follow symlinks on a POSIX client. The > * client should be doing this. > */ >@@ -365,12 +364,10 @@ NTSTATUS fd_open(struct connection_struct *conn, > if ((fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) || !lp_follow_symlinks(SNUM(conn))) { > flags |= O_NOFOLLOW; > } >-#endif > > fsp->fh->fd = SMB_VFS_OPEN(conn, smb_fname, fsp, flags, mode); > if (fsp->fh->fd == -1) { > int posix_errno = errno; >-#ifdef O_NOFOLLOW > #if defined(ENOTSUP) && defined(OSF1) > /* handle special Tru64 errno */ > if (errno == ENOTSUP) { >@@ -387,7 +384,6 @@ NTSTATUS fd_open(struct connection_struct *conn, > if (errno == EMLINK) { > posix_errno = ELOOP; > } >-#endif /* O_NOFOLLOW */ > status = map_nt_error_from_unix(posix_errno); > if (errno == EMFILE) { > static time_t last_warned = 0L; >-- >2.9.3 > > >From a34ff44b2cbd396c678aebfc299495ddad6b91d1 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Thu, 15 Dec 2016 12:56:08 -0800 >Subject: [PATCH 09/11] s3: smbd: Move special handling of symlink errno's into > a utility function. > >CVE-2017-2619 > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 > >Signed-off-by: Jeremy Allison <jra@samba.org> >--- > source3/smbd/open.c | 43 ++++++++++++++++++++++++++----------------- > 1 file changed, 26 insertions(+), 17 deletions(-) > >diff --git a/source3/smbd/open.c b/source3/smbd/open.c >index 03a994a..616363d 100644 >--- a/source3/smbd/open.c >+++ b/source3/smbd/open.c >@@ -345,6 +345,31 @@ static NTSTATUS check_base_file_access(struct connection_struct *conn, > } > > /**************************************************************************** >+ Handle differing symlink errno's >+****************************************************************************/ >+ >+static int link_errno_convert(int err) >+{ >+#if defined(ENOTSUP) && defined(OSF1) >+ /* handle special Tru64 errno */ >+ if (err == ENOTSUP) { >+ err = ELOOP; >+ } >+#endif /* ENOTSUP */ >+#ifdef EFTYPE >+ /* fix broken NetBSD errno */ >+ if (err == EFTYPE) { >+ err = ELOOP; >+ } >+#endif /* EFTYPE */ >+ /* fix broken FreeBSD errno */ >+ if (err == EMLINK) { >+ err = ELOOP; >+ } >+ return err; >+} >+ >+/**************************************************************************** > fd support routines - attempt to do a dos_open. > ****************************************************************************/ > >@@ -367,23 +392,7 @@ NTSTATUS fd_open(struct connection_struct *conn, > > fsp->fh->fd = SMB_VFS_OPEN(conn, smb_fname, fsp, flags, mode); > if (fsp->fh->fd == -1) { >- int posix_errno = errno; >-#if defined(ENOTSUP) && defined(OSF1) >- /* handle special Tru64 errno */ >- if (errno == ENOTSUP) { >- posix_errno = ELOOP; >- } >-#endif /* ENOTSUP */ >-#ifdef EFTYPE >- /* fix broken NetBSD errno */ >- if (errno == EFTYPE) { >- posix_errno = ELOOP; >- } >-#endif /* EFTYPE */ >- /* fix broken FreeBSD errno */ >- if (errno == EMLINK) { >- posix_errno = ELOOP; >- } >+ int posix_errno = link_errno_convert(errno); > status = map_nt_error_from_unix(posix_errno); > if (errno == EMFILE) { > static time_t last_warned = 0L; >-- >2.9.3 > > >From 6c455324714936063d77ff15997fcaf651d40a5f Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Thu, 15 Dec 2016 13:04:46 -0800 >Subject: [PATCH 10/11] s3: smbd: Add the core functions to prevent symlink > open races. > >CVE-2017-2619 > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 > >Signed-off-by: Jeremy Allison <jra@samba.org> >--- > source3/smbd/open.c | 237 ++++++++++++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 237 insertions(+) > >diff --git a/source3/smbd/open.c b/source3/smbd/open.c >index 616363d..954cd9c 100644 >--- a/source3/smbd/open.c >+++ b/source3/smbd/open.c >@@ -369,6 +369,243 @@ static int link_errno_convert(int err) > return err; > } > >+static int non_widelink_open(struct connection_struct *conn, >+ const char *conn_rootdir, >+ files_struct *fsp, >+ struct smb_filename *smb_fname, >+ int flags, >+ mode_t mode, >+ unsigned int link_depth); >+ >+/**************************************************************************** >+ Follow a symlink in userspace. >+****************************************************************************/ >+ >+static int process_symlink_open(struct connection_struct *conn, >+ const char *conn_rootdir, >+ files_struct *fsp, >+ struct smb_filename *smb_fname, >+ int flags, >+ mode_t mode, >+ unsigned int link_depth) >+{ >+ int fd = -1; >+ char *link_target = NULL; >+ int link_len = -1; >+ char *oldwd = NULL; >+ size_t rootdir_len = 0; >+ char *resolved_name = NULL; >+ bool matched = false; >+ int saved_errno = 0; >+ >+ /* >+ * Ensure we don't get stuck in a symlink loop. >+ */ >+ link_depth++; >+ if (link_depth >= 20) { >+ errno = ELOOP; >+ goto out; >+ } >+ >+ /* Allocate space for the link target. */ >+ link_target = talloc_array(talloc_tos(), char, PATH_MAX); >+ if (link_target == NULL) { >+ errno = ENOMEM; >+ goto out; >+ } >+ >+ /* Read the link target. */ >+ link_len = SMB_VFS_READLINK(conn, >+ smb_fname->base_name, >+ link_target, >+ PATH_MAX - 1); >+ if (link_len == -1) { >+ goto out; >+ } >+ >+ /* Ensure it's at least null terminated. */ >+ link_target[link_len] = '\0'; >+ >+ /* Convert to an absolute path. */ >+ resolved_name = SMB_VFS_REALPATH(conn, link_target); >+ if (resolved_name == NULL) { >+ goto out; >+ } >+ >+ /* >+ * We know conn_rootdir starts with '/' and >+ * does not end in '/'. FIXME ! Should we >+ * smb_assert this ? >+ */ >+ rootdir_len = strlen(conn_rootdir); >+ >+ matched = (strncmp(conn_rootdir, resolved_name, rootdir_len) == 0); >+ if (!matched) { >+ errno = EACCES; >+ goto out; >+ } >+ >+ /* >+ * Turn into a path relative to the share root. >+ */ >+ if (resolved_name[rootdir_len] == '\0') { >+ /* Link to the root of the share. */ >+ smb_fname->base_name = talloc_strdup(talloc_tos(), "."); >+ if (smb_fname->base_name == NULL) { >+ errno = ENOMEM; >+ goto out; >+ } >+ } else if (resolved_name[rootdir_len] == '/') { >+ smb_fname->base_name = &resolved_name[rootdir_len+1]; >+ } else { >+ errno = EACCES; >+ goto out; >+ } >+ >+ oldwd = vfs_GetWd(talloc_tos(), conn); >+ if (oldwd == NULL) { >+ goto out; >+ } >+ >+ /* Ensure we operate from the root of the share. */ >+ if (vfs_ChDir(conn, conn_rootdir) == -1) { >+ goto out; >+ } >+ >+ /* And do it all again.. */ >+ fd = non_widelink_open(conn, >+ conn_rootdir, >+ fsp, >+ smb_fname, >+ flags, >+ mode, >+ link_depth); >+ if (fd == -1) { >+ saved_errno = errno; >+ } >+ >+ out: >+ >+ SAFE_FREE(resolved_name); >+ TALLOC_FREE(link_target); >+ if (oldwd != NULL) { >+ int ret = vfs_ChDir(conn, oldwd); >+ if (ret == -1) { >+ smb_panic("unable to get back to old directory\n"); >+ } >+ TALLOC_FREE(oldwd); >+ } >+ if (saved_errno != 0) { >+ errno = saved_errno; >+ } >+ return fd; >+} >+ >+/**************************************************************************** >+ Non-widelink open. >+****************************************************************************/ >+ >+static int non_widelink_open(struct connection_struct *conn, >+ const char *conn_rootdir, >+ files_struct *fsp, >+ struct smb_filename *smb_fname, >+ int flags, >+ mode_t mode, >+ unsigned int link_depth) >+{ >+ NTSTATUS status; >+ int fd = -1; >+ struct smb_filename *smb_fname_rel = NULL; >+ int saved_errno = 0; >+ char *oldwd = NULL; >+ char *parent_dir = NULL; >+ const char *final_component = NULL; >+ >+ if (!parent_dirname(talloc_tos(), >+ smb_fname->base_name, >+ &parent_dir, >+ &final_component)) { >+ goto out; >+ } >+ >+ oldwd = vfs_GetWd(talloc_tos(), conn); >+ if (oldwd == NULL) { >+ goto out; >+ } >+ >+ /* Pin parent directory in place. */ >+ if (vfs_ChDir(conn, parent_dir) == -1) { >+ goto out; >+ } >+ >+ /* Ensure the relative path is below the share. */ >+ status = check_reduced_name(conn, final_component); >+ if (!NT_STATUS_IS_OK(status)) { >+ saved_errno = map_errno_from_nt_status(status); >+ goto out; >+ } >+ >+ smb_fname_rel = synthetic_smb_fname(talloc_tos(), >+ final_component, >+ smb_fname->stream_name, >+ &smb_fname->st); >+ >+ flags |= O_NOFOLLOW; >+ >+ { >+ struct smb_filename *tmp_name = fsp->fsp_name; >+ fsp->fsp_name = smb_fname_rel; >+ fd = SMB_VFS_OPEN(conn, smb_fname_rel, fsp, flags, mode); >+ fsp->fsp_name = tmp_name; >+ } >+ >+ if (fd == -1) { >+ saved_errno = link_errno_convert(errno); >+ if (saved_errno == ELOOP) { >+ if (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) { >+ /* Never follow symlinks on posix open. */ >+ goto out; >+ } >+ if (!lp_follow_symlinks(SNUM(conn))) { >+ /* Explicitly no symlinks. */ >+ goto out; >+ } >+ /* >+ * We have a symlink. Follow in userspace >+ * to ensure it's under the share definition. >+ */ >+ fd = process_symlink_open(conn, >+ conn_rootdir, >+ fsp, >+ smb_fname_rel, >+ flags, >+ mode, >+ link_depth); >+ if (fd == -1) { >+ saved_errno = >+ link_errno_convert(errno); >+ } >+ } >+ } >+ >+ out: >+ >+ TALLOC_FREE(parent_dir); >+ TALLOC_FREE(smb_fname_rel); >+ >+ if (oldwd != NULL) { >+ int ret = vfs_ChDir(conn, oldwd); >+ if (ret == -1) { >+ smb_panic("unable to get back to old directory\n"); >+ } >+ TALLOC_FREE(oldwd); >+ } >+ if (saved_errno != 0) { >+ errno = saved_errno; >+ } >+ return fd; >+} >+ > /**************************************************************************** > fd support routines - attempt to do a dos_open. > ****************************************************************************/ >-- >2.9.3 > > >From 0eb718b5cc05adbcb20ac5b9b0eee71aa2af81ac Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Thu, 15 Dec 2016 13:06:31 -0800 >Subject: [PATCH 11/11] s3: smbd: Use the new non_widelink_open() function. > >CVE-2017-2619 > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=12496 > >Signed-off-by: Jeremy Allison <jra@samba.org> >--- > source3/smbd/open.c | 23 ++++++++++++++++++++++- > 1 file changed, 22 insertions(+), 1 deletion(-) > >diff --git a/source3/smbd/open.c b/source3/smbd/open.c >index 954cd9c..7274ae4 100644 >--- a/source3/smbd/open.c >+++ b/source3/smbd/open.c >@@ -627,7 +627,28 @@ NTSTATUS fd_open(struct connection_struct *conn, > flags |= O_NOFOLLOW; > } > >- fsp->fh->fd = SMB_VFS_OPEN(conn, smb_fname, fsp, flags, mode); >+ /* Ensure path is below share definition. */ >+ if (!lp_widelinks(SNUM(conn))) { >+ const char *conn_rootdir = SMB_VFS_CONNECTPATH(conn, >+ smb_fname->base_name); >+ if (conn_rootdir == NULL) { >+ return NT_STATUS_NO_MEMORY; >+ } >+ /* >+ * Only follow symlinks within a share >+ * definition. >+ */ >+ fsp->fh->fd = non_widelink_open(conn, >+ conn_rootdir, >+ fsp, >+ smb_fname, >+ flags, >+ mode, >+ 0); >+ } else { >+ fsp->fh->fd = SMB_VFS_OPEN(conn, smb_fname, fsp, flags, mode); >+ } >+ > if (fsp->fh->fd == -1) { > int posix_errno = link_errno_convert(errno); > status = map_nt_error_from_unix(posix_errno); >-- >2.9.3 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
Actions:
View
|
Diff
Attachments on
bug 43679
: 8496 |
8561
|
8562
|
8563
|
8564
|
8565
|
8566
|
8593