diff -Nru samba-4.4.5+dfsg/debian/changelog samba-4.4.5+dfsg/debian/changelog --- samba-4.4.5+dfsg/debian/changelog 2016-12-12 13:12:03.000000000 +0000 +++ samba-4.4.5+dfsg/debian/changelog 2017-03-20 14:47:39.000000000 +0000 @@ -1,3 +1,12 @@ +samba (2:4.4.5+dfsg-2ubuntu5.4) yakkety-security; urgency=medium + + * SECURITY UPDATE: Symlink race allows access outside share definition + - debian/patches/CVE-2017-2619/*.patch: backport security fix and + prerequisite patches from upstream. + - CVE-2017-2619 + + -- Marc Deslauriers Mon, 20 Mar 2017 10:47:39 -0400 + samba (2:4.4.5+dfsg-2ubuntu5.2) yakkety-security; urgency=medium * SECURITY UPDATE: remote code execution via heap overflow in NDR parsing diff -Nru samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12387.patch samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12387.patch --- samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12387.patch 1970-01-01 00:00:00.000000000 +0000 +++ samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12387.patch 2017-03-16 12:56:41.000000000 +0000 @@ -0,0 +1,38 @@ +From 6aec65c2333270f497d0ea21bdafc5e2d3676773 Mon Sep 17 00:00:00 2001 +From: Jeremy Allison +Date: Fri, 21 Oct 2016 11:04:02 -0700 +Subject: [PATCH] s3: vfs: streams_depot. Use conn->connectpath not conn->cwd. + +conn->cwd can change over the life of the connection, +conn->connectpath remains static. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12387 + +Signed-off-by: Jeremy Allison +Reviewed-by: Uri Simchoni + +Autobuild-User(master): Uri Simchoni +Autobuild-Date(master): Mon Oct 24 23:52:48 CEST 2016 on sn-devel-144 + +(cherry picked from commit 1366385d1c3e9ac0556e954864e60e72f6906942) +--- + source3/modules/vfs_streams_depot.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/source3/modules/vfs_streams_depot.c b/source3/modules/vfs_streams_depot.c +index 5964852..bb8d5b9 100644 +--- a/source3/modules/vfs_streams_depot.c ++++ b/source3/modules/vfs_streams_depot.c +@@ -128,7 +128,8 @@ static char *stream_dir(vfs_handle_struct *handle, + check_valid = lp_parm_bool(SNUM(handle->conn), + "streams_depot", "check_valid", true); + +- tmp = talloc_asprintf(talloc_tos(), "%s/.streams", handle->conn->cwd); ++ tmp = talloc_asprintf(talloc_tos(), "%s/.streams", ++ handle->conn->connectpath); + + if (tmp == NULL) { + errno = ENOMEM; +-- +1.9.1 + diff -Nru samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12499.patch samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12499.patch --- samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12499.patch 1970-01-01 00:00:00.000000000 +0000 +++ samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12499.patch 2017-03-16 12:56:46.000000000 +0000 @@ -0,0 +1,35 @@ +From bb453f5b558de3a9d601005ba002c766672859c6 Mon Sep 17 00:00:00 2001 +From: Jeremy Allison +Date: Fri, 27 Jan 2017 09:09:56 -0800 +Subject: [PATCH] s3: vfs: dirsort doesn't handle opendir of "." correctly. + +Needs to store $cwd path for correct sorting. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12499 + +Back-port from commit e2f34116ab6328e2b872999dc7c4bcda69c03ab2. + +Signed-off-by: Jeremy Allison +Reviewed-by: Uri Simchoni +--- + source3/modules/vfs_dirsort.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/source3/modules/vfs_dirsort.c b/source3/modules/vfs_dirsort.c +index d164088..0e923e6 100644 +--- a/source3/modules/vfs_dirsort.c ++++ b/source3/modules/vfs_dirsort.c +@@ -137,6 +137,10 @@ static DIR *dirsort_opendir(vfs_handle_struct *handle, + return NULL; + } + ++ if (ISDOT(data->smb_fname->base_name)) { ++ data->smb_fname->base_name = vfs_GetWd(data, handle->conn); ++ } ++ + /* Open the underlying directory and count the number of entries */ + data->source_directory = SMB_VFS_NEXT_OPENDIR(handle, fname, mask, + attr); +-- +1.9.1 + diff -Nru samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-10.patch samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-10.patch --- samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-10.patch 1970-01-01 00:00:00.000000000 +0000 +++ samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-10.patch 2017-03-16 12:57:51.000000000 +0000 @@ -0,0 +1,60 @@ +From 6cc2fdbf91d1f549360a9d9aa1aa50decbbce40e Mon Sep 17 00:00:00 2001 +From: Jeremy Allison +Date: Fri, 20 Jan 2017 11:54:56 -0800 +Subject: [PATCH] s3: VFS: shadow_copy2: Add a wrapper function to call the + original shadow_copy2_strip_snapshot(). + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12531 + +Allows an extra (currently unused) parameter to be added. + +Signed-off-by: Jeremy Allison +Reviewed-by: Uri Simchoni +(backported from commit 5aa1ea95157475dfd2d056f0158b14b2b90895a9) +--- + source3/modules/vfs_shadow_copy2.c | 19 +++++++++++++++++-- + 1 file changed, 17 insertions(+), 2 deletions(-) + +diff --git a/source3/modules/vfs_shadow_copy2.c b/source3/modules/vfs_shadow_copy2.c +index 8356645..111ea03 100644 +--- a/source3/modules/vfs_shadow_copy2.c ++++ b/source3/modules/vfs_shadow_copy2.c +@@ -224,11 +224,12 @@ static char *shadow_copy2_snapshot_path(TALLOC_CTX *mem_ctx, + * handed in via the smb layer. + * Returns the parsed timestamp and the stripped filename. + */ +-static bool shadow_copy2_strip_snapshot(TALLOC_CTX *mem_ctx, ++static bool shadow_copy2_strip_snapshot_internal(TALLOC_CTX *mem_ctx, + struct vfs_handle_struct *handle, + const char *name, + time_t *ptimestamp, +- char **pstripped) ++ char **pstripped, ++ char **psnappath) + { + struct tm tm; + time_t timestamp = 0; +@@ -402,6 +403,20 @@ no_snapshot: + return true; + } + ++static bool shadow_copy2_strip_snapshot(TALLOC_CTX *mem_ctx, ++ struct vfs_handle_struct *handle, ++ const char *orig_name, ++ time_t *ptimestamp, ++ char **pstripped) ++{ ++ return shadow_copy2_strip_snapshot_internal(mem_ctx, ++ handle, ++ orig_name, ++ ptimestamp, ++ pstripped, ++ NULL); ++} ++ + static char *shadow_copy2_find_mount_point(TALLOC_CTX *mem_ctx, + vfs_handle_struct *handle) + { +-- +1.9.1 + diff -Nru samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-11.patch samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-11.patch --- samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-11.patch 1970-01-01 00:00:00.000000000 +0000 +++ samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-11.patch 2017-03-16 12:57:56.000000000 +0000 @@ -0,0 +1,40 @@ +From d9acfc47aad6d0870c9deb1e2385aff0c8e4a7a5 Mon Sep 17 00:00:00 2001 +From: Jeremy Allison +Date: Fri, 20 Jan 2017 11:56:21 -0800 +Subject: [PATCH] s3: VFS: shadow_copy2: Change a parameter name. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12531 + +Allows easy substitution later. + +Signed-off-by: Jeremy Allison +Reviewed-by: Uri Simchoni +(backported from commit 2887465108aef5e2e7c64417437ecb86c7460e16) +--- + source3/modules/vfs_shadow_copy2.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/source3/modules/vfs_shadow_copy2.c b/source3/modules/vfs_shadow_copy2.c +index 111ea03..53d3e74 100644 +--- a/source3/modules/vfs_shadow_copy2.c ++++ b/source3/modules/vfs_shadow_copy2.c +@@ -226,7 +226,7 @@ static char *shadow_copy2_snapshot_path(TALLOC_CTX *mem_ctx, + */ + static bool shadow_copy2_strip_snapshot_internal(TALLOC_CTX *mem_ctx, + struct vfs_handle_struct *handle, +- const char *name, ++ const char *orig_name, + time_t *ptimestamp, + char **pstripped, + char **psnappath) +@@ -241,6 +241,7 @@ static bool shadow_copy2_strip_snapshot_internal(TALLOC_CTX *mem_ctx, + const char *snapdir; + ssize_t snapdirlen; + ptrdiff_t len_before_gmt; ++ const char *name = orig_name; + + SMB_VFS_HANDLE_GET_DATA(handle, config, struct shadow_copy2_config, + return false); +-- +1.9.1 + diff -Nru samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-12.patch samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-12.patch --- samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-12.patch 1970-01-01 00:00:00.000000000 +0000 +++ samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-12.patch 2017-03-16 12:58:00.000000000 +0000 @@ -0,0 +1,81 @@ +From 173bd073004352d8564485c56a19b167596b1fd5 Mon Sep 17 00:00:00 2001 +From: Jeremy Allison +Date: Fri, 20 Jan 2017 12:00:08 -0800 +Subject: [PATCH] s3: VFS: shadow_copy2: Add two currently unused functions to + make pathnames absolute or relative to $cwd. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12531 + +Signed-off-by: Jeremy Allison +Reviewed-by: Uri Simchoni +(backported from commit 9d65107b8f2864dba8d41b3316c483b3f36d0697) +--- + source3/modules/vfs_shadow_copy2.c | 45 ++++++++++++++++++++++++++++++++++++++ + 1 file changed, 45 insertions(+) + +diff --git a/source3/modules/vfs_shadow_copy2.c b/source3/modules/vfs_shadow_copy2.c +index 53d3e74..c03bf46 100644 +--- a/source3/modules/vfs_shadow_copy2.c ++++ b/source3/modules/vfs_shadow_copy2.c +@@ -34,6 +34,7 @@ + #include "system/filesys.h" + #include "include/ntioctl.h" + #include "util_tdb.h" ++#include "lib/util_path.h" + + struct shadow_copy2_config { + char *gmt_format; +@@ -219,6 +220,50 @@ static char *shadow_copy2_snapshot_path(TALLOC_CTX *mem_ctx, + return result; + } + ++static char *make_path_absolute(TALLOC_CTX *mem_ctx, ++ struct shadow_copy2_config *config, ++ const char *name) ++{ ++ char *newpath = NULL; ++ char *abs_path = NULL; ++ ++ if (name[0] != '/') { ++ newpath = talloc_asprintf(mem_ctx, ++ "%s/%s", ++ config->shadow_cwd, ++ name); ++ if (newpath == NULL) { ++ return NULL; ++ } ++ name = newpath; ++ } ++ abs_path = canonicalize_absolute_path(mem_ctx, name); ++ TALLOC_FREE(newpath); ++ return abs_path; ++} ++ ++/* Return a $cwd-relative path. */ ++static bool make_relative_path(const char *cwd, char *abs_path) ++{ ++ size_t cwd_len = strlen(cwd); ++ size_t abs_len = strlen(abs_path); ++ ++ if (abs_len < cwd_len) { ++ return false; ++ } ++ if (memcmp(abs_path, cwd, cwd_len) != 0) { ++ return false; ++ } ++ if (abs_path[cwd_len] != '/' && abs_path[cwd_len] != '\0') { ++ return false; ++ } ++ if (abs_path[cwd_len] == '/') { ++ cwd_len++; ++ } ++ memmove(abs_path, &abs_path[cwd_len], abs_len + 1 - cwd_len); ++ return true; ++} ++ + /** + * Strip a snapshot component from a filename as + * handed in via the smb layer. +-- +1.9.1 + diff -Nru samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-13.patch samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-13.patch --- samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-13.patch 1970-01-01 00:00:00.000000000 +0000 +++ samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-13.patch 2017-03-16 12:58:04.000000000 +0000 @@ -0,0 +1,123 @@ +From 0d1a281140a17fd4317fdfaddc7f14784e3154eb Mon Sep 17 00:00:00 2001 +From: Jeremy Allison +Date: Fri, 20 Jan 2017 12:06:55 -0800 +Subject: [PATCH] s3: VFS: shadow_copy2: Fix chdir to store off the needed + private variables. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12531 + +This is not yet used, the users of this will be added later. + +Signed-off-by: Jeremy Allison +Reviewed-by: Uri Simchoni +(backported from commit 27340df4b52e4341f134667c59d71656a7a1fdae) +--- + source3/modules/vfs_shadow_copy2.c | 81 ++++++++++++++++++++++++++++++++------ + 1 file changed, 68 insertions(+), 13 deletions(-) + +diff --git a/source3/modules/vfs_shadow_copy2.c b/source3/modules/vfs_shadow_copy2.c +index c03bf46..5b1685d 100644 +--- a/source3/modules/vfs_shadow_copy2.c ++++ b/source3/modules/vfs_shadow_copy2.c +@@ -1080,30 +1080,85 @@ static int shadow_copy2_chown(vfs_handle_struct *handle, const char *fname, + return ret; + } + ++static void store_cwd_data(vfs_handle_struct *handle, ++ const char *connectpath) ++{ ++ struct shadow_copy2_config *config = NULL; ++ char *cwd = NULL; ++ ++ SMB_VFS_HANDLE_GET_DATA(handle, config, struct shadow_copy2_config, ++ return); ++ ++ TALLOC_FREE(config->shadow_cwd); ++ cwd = SMB_VFS_NEXT_GETWD(handle); ++ if (cwd == NULL) { ++ smb_panic("getwd failed\n"); ++ } ++ DBG_DEBUG("shadow cwd = %s\n", cwd); ++ config->shadow_cwd = talloc_strdup(config, cwd); ++ SAFE_FREE(cwd); ++ if (config->shadow_cwd == NULL) { ++ smb_panic("talloc failed\n"); ++ } ++ TALLOC_FREE(config->shadow_connectpath); ++ if (connectpath) { ++ DBG_DEBUG("shadow conectpath = %s\n", connectpath); ++ config->shadow_connectpath = talloc_strdup(config, connectpath); ++ if (config->shadow_connectpath == NULL) { ++ smb_panic("talloc failed\n"); ++ } ++ } ++} ++ + static int shadow_copy2_chdir(vfs_handle_struct *handle, + const char *fname) + { + time_t timestamp = 0; + char *stripped = NULL; +- int ret, saved_errno; +- char *conv; ++ char *snappath = NULL; ++ int ret = -1; ++ int saved_errno = 0; ++ char *conv = NULL; ++ size_t rootpath_len = 0; + +- if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, fname, +- ×tamp, &stripped)) { ++ if (!shadow_copy2_strip_snapshot_internal(talloc_tos(), handle, fname, ++ ×tamp, &stripped, &snappath)) { + return -1; + } +- if (timestamp == 0) { +- return SMB_VFS_NEXT_CHDIR(handle, fname); ++ if (stripped != NULL) { ++ conv = shadow_copy2_do_convert(talloc_tos(), ++ handle, ++ stripped, ++ timestamp, ++ &rootpath_len); ++ TALLOC_FREE(stripped); ++ if (conv == NULL) { ++ return -1; ++ } ++ fname = conv; + } +- conv = shadow_copy2_convert(talloc_tos(), handle, stripped, timestamp); +- TALLOC_FREE(stripped); +- if (conv == NULL) { +- return -1; ++ ++ ret = SMB_VFS_NEXT_CHDIR(handle, fname); ++ if (ret == -1) { ++ saved_errno = errno; + } +- ret = SMB_VFS_NEXT_CHDIR(handle, conv); +- saved_errno = errno; ++ ++ if (ret == 0) { ++ if (conv != NULL && rootpath_len != 0) { ++ conv[rootpath_len] = '\0'; ++ } else if (snappath != 0) { ++ TALLOC_FREE(conv); ++ conv = snappath; ++ } ++ store_cwd_data(handle, conv); ++ } ++ ++ TALLOC_FREE(stripped); + TALLOC_FREE(conv); +- errno = saved_errno; ++ ++ if (saved_errno != 0) { ++ errno = saved_errno; ++ } + return ret; + } + +-- +1.9.1 + diff -Nru samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-14.patch samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-14.patch --- samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-14.patch 1970-01-01 00:00:00.000000000 +0000 +++ samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-14.patch 2017-03-16 12:58:16.000000000 +0000 @@ -0,0 +1,39 @@ +From 52439d70d766062ee74d64aeeccf9838c6c9ae74 Mon Sep 17 00:00:00 2001 +From: Jeremy Allison +Date: Fri, 20 Jan 2017 12:09:08 -0800 +Subject: [PATCH] s3: VFS: Allow shadow_copy2_connectpath() to return the + cached path derived from $cwd. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12531 + +Signed-off-by: Jeremy Allison +Reviewed-by: Uri Simchoni +(backported from commit 42bd1acad75a6b5ea81fe4b30c067dd82623c042) +--- + source3/modules/vfs_shadow_copy2.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +Index: samba-4.4.5+dfsg/source3/modules/vfs_shadow_copy2.c +=================================================================== +--- samba-4.4.5+dfsg.orig/source3/modules/vfs_shadow_copy2.c 2017-03-16 08:58:13.078659794 -0400 ++++ samba-4.4.5+dfsg/source3/modules/vfs_shadow_copy2.c 2017-03-16 08:58:13.074659747 -0400 +@@ -1919,9 +1919,19 @@ + char *result = NULL; + int saved_errno; + size_t rootpath_len = 0; ++ struct shadow_copy2_config *config = NULL; ++ ++ SMB_VFS_HANDLE_GET_DATA(handle, config, struct shadow_copy2_config, ++ return NULL); + + DBG_DEBUG("Calc connect path for [%s]\n", fname); + ++ if (config->shadow_connectpath != NULL) { ++ DBG_DEBUG("cached connect path is [%s]\n", ++ config->shadow_connectpath); ++ return config->shadow_connectpath; ++ } ++ + if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, fname, + ×tamp, &stripped)) { + goto done; diff -Nru samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-15.patch samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-15.patch --- samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-15.patch 1970-01-01 00:00:00.000000000 +0000 +++ samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-15.patch 2017-03-16 12:58:56.000000000 +0000 @@ -0,0 +1,35 @@ +From 50d3a7011237fcb36bf9b53f7db8846e854453d4 Mon Sep 17 00:00:00 2001 +From: Jeremy Allison +Date: Thu, 26 Jan 2017 10:24:52 -0800 +Subject: [PATCH] s3: VFS: Ensure shadow:format cannot contain a / path + separator. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12531 + +Signed-off-by: Jeremy Allison +Reviewed-by: Uri Simchoni +(backported from commit cd4f940162b17e4f7345d392326a31ae478230fa) +--- + source3/modules/vfs_shadow_copy2.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +Index: samba-4.4.5+dfsg/source3/modules/vfs_shadow_copy2.c +=================================================================== +--- samba-4.4.5+dfsg.orig/source3/modules/vfs_shadow_copy2.c 2017-03-16 08:58:53.387130552 -0400 ++++ samba-4.4.5+dfsg/source3/modules/vfs_shadow_copy2.c 2017-03-16 08:58:53.387130552 -0400 +@@ -2070,6 +2070,15 @@ + return -1; + } + ++ /* config->gmt_format must not contain a path separator. */ ++ if (strchr(config->gmt_format, '/') != NULL) { ++ DEBUG(0, ("shadow:format %s must not contain a /" ++ "character. Unable to initialize module.\n", ++ config->gmt_format)); ++ errno = EINVAL; ++ return -1; ++ } ++ + config->use_sscanf = lp_parm_bool(SNUM(handle->conn), + "shadow", "sscanf", false); + diff -Nru samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-16.patch samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-16.patch --- samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-16.patch 1970-01-01 00:00:00.000000000 +0000 +++ samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-16.patch 2017-03-16 12:58:59.000000000 +0000 @@ -0,0 +1,138 @@ +From 7a831814592505d004f83ac49ec25b02f4f2d374 Mon Sep 17 00:00:00 2001 +From: Jeremy Allison +Date: Thu, 26 Jan 2017 10:35:50 -0800 +Subject: [PATCH] s3: VFS: Add utility function check_for_converted_path(). + +Detects an already converted path. Not yet used. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12531 + +Signed-off-by: Jeremy Allison +Reviewed-by: Uri Simchoni +(backported from commit b94dc85d339c9a10496edd07b85bdd7808d2e332) +--- + source3/modules/vfs_shadow_copy2.c | 108 +++++++++++++++++++++++++++++++++++++ + 1 file changed, 108 insertions(+) + +diff --git a/source3/modules/vfs_shadow_copy2.c b/source3/modules/vfs_shadow_copy2.c +index 78f9079..6c8e43c 100644 +--- a/source3/modules/vfs_shadow_copy2.c ++++ b/source3/modules/vfs_shadow_copy2.c +@@ -264,6 +264,114 @@ static bool make_relative_path(const char *cwd, char *abs_path) + return true; + } + ++static bool shadow_copy2_snapshot_to_gmt(vfs_handle_struct *handle, ++ const char *name, ++ char *gmt, size_t gmt_len); ++ ++/* ++ * Check if an incoming filename is already a snapshot converted pathname. ++ * ++ * If so, it returns the pathname truncated at the snapshot point which ++ * will be used as the connectpath. ++ */ ++ ++static int check_for_converted_path(TALLOC_CTX *mem_ctx, ++ struct vfs_handle_struct *handle, ++ struct shadow_copy2_config *config, ++ char *abs_path, ++ bool *ppath_already_converted, ++ char **pconnectpath) ++{ ++ size_t snapdirlen = 0; ++ char *p = strstr_m(abs_path, config->snapdir); ++ char *q = NULL; ++ char *connect_path = NULL; ++ char snapshot[GMT_NAME_LEN+1]; ++ ++ *ppath_already_converted = false; ++ ++ if (p == NULL) { ++ /* Must at least contain shadow:snapdir. */ ++ return 0; ++ } ++ ++ if (config->snapdir[0] == '/' && ++ p != abs_path) { ++ /* Absolute shadow:snapdir must be at the start. */ ++ return 0; ++ } ++ ++ snapdirlen = strlen(config->snapdir); ++ if (p[snapdirlen] != '/') { ++ /* shadow:snapdir must end as a separate component. */ ++ return 0; ++ } ++ ++ if (p > abs_path && p[-1] != '/') { ++ /* shadow:snapdir must start as a separate component. */ ++ return 0; ++ } ++ ++ p += snapdirlen; ++ p++; /* Move past the / */ ++ ++ /* ++ * Need to return up to the next path ++ * component after the time. ++ * This will be used as the connectpath. ++ */ ++ q = strchr(p, '/'); ++ if (q == NULL) { ++ /* ++ * No next path component. ++ * Use entire string. ++ */ ++ connect_path = talloc_strdup(mem_ctx, ++ abs_path); ++ } else { ++ connect_path = talloc_strndup(mem_ctx, ++ abs_path, ++ q - abs_path); ++ } ++ if (connect_path == NULL) { ++ return ENOMEM; ++ } ++ ++ /* ++ * Point p at the same offset in connect_path as ++ * it is in abs_path. ++ */ ++ ++ p = &connect_path[p - abs_path]; ++ ++ /* ++ * Now ensure there is a time string at p. ++ * The SMB-format @GMT-token string is returned ++ * in snapshot. ++ */ ++ ++ if (!shadow_copy2_snapshot_to_gmt(handle, ++ p, ++ snapshot, ++ sizeof(snapshot))) { ++ TALLOC_FREE(connect_path); ++ return 0; ++ } ++ ++ if (pconnectpath != NULL) { ++ *pconnectpath = connect_path; ++ } ++ ++ *ppath_already_converted = true; ++ ++ DBG_DEBUG("path |%s| is already converted. " ++ "connect path = |%s|\n", ++ abs_path, ++ connect_path); ++ ++ return 0; ++} ++ + /** + * Strip a snapshot component from a filename as + * handed in via the smb layer. +-- +1.9.1 + diff -Nru samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-17.patch samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-17.patch --- samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-17.patch 1970-01-01 00:00:00.000000000 +0000 +++ samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-17.patch 2017-03-16 12:59:03.000000000 +0000 @@ -0,0 +1,310 @@ +From eef845bfeff709dab07609590955efde54c4b377 Mon Sep 17 00:00:00 2001 +From: Jeremy Allison +Date: Thu, 26 Jan 2017 10:49:51 -0800 +Subject: [PATCH] s3: VFS: shadow_copy2: Fix module to work with variable + current working directory. + +Completely cleans up the horrible shadow_copy2_strip_snapshot() +and adds an explaination of what it's actually trying to do. + +* This function does two things. +* +* 1). Checks if an incoming filename is already a +* snapshot converted pathname. +* If so, it returns the pathname truncated +* at the snapshot point which will be used +* as the connectpath, and then does an early return. +* +* 2). Checks if an incoming filename contains an +* SMB-layer @GMT- style timestamp. +* If so, it strips the timestamp, and returns +* both the timestamp and the stripped path +* (making it cwd-relative). + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12531 + +Signed-off-by: Jeremy Allison +Reviewed-by: Uri Simchoni +(backported from commit 128d5f27cd42b0c7efcbe3d28fe3eee881e0734b) +--- + source3/modules/vfs_shadow_copy2.c | 189 ++++++++++++++++++------------------- + 1 file changed, 92 insertions(+), 97 deletions(-) + +diff --git a/source3/modules/vfs_shadow_copy2.c b/source3/modules/vfs_shadow_copy2.c +index 6c8e43c..b096d4e 100644 +--- a/source3/modules/vfs_shadow_copy2.c ++++ b/source3/modules/vfs_shadow_copy2.c +@@ -373,10 +373,21 @@ static int check_for_converted_path(TALLOC_CTX *mem_ctx, + } + + /** +- * Strip a snapshot component from a filename as +- * handed in via the smb layer. +- * Returns the parsed timestamp and the stripped filename. ++ * This function does two things. ++ * ++ * 1). Checks if an incoming filename is already a ++ * snapshot converted pathname. ++ * If so, it returns the pathname truncated ++ * at the snapshot point which will be used ++ * as the connectpath, and then does an early return. ++ * ++ * 2). Checks if an incoming filename contains an ++ * SMB-layer @GMT- style timestamp. ++ * If so, it strips the timestamp, and returns ++ * both the timestamp and the stripped path ++ * (making it cwd-relative). + */ ++ + static bool shadow_copy2_strip_snapshot_internal(TALLOC_CTX *mem_ctx, + struct vfs_handle_struct *handle, + const char *orig_name, +@@ -391,62 +402,72 @@ static bool shadow_copy2_strip_snapshot_internal(TALLOC_CTX *mem_ctx, + char *stripped = NULL; + size_t rest_len, dst_len; + struct shadow_copy2_config *config; +- const char *snapdir; +- ssize_t snapdirlen; + ptrdiff_t len_before_gmt; + const char *name = orig_name; ++ char *abs_path = NULL; ++ bool ret = true; ++ bool already_converted = false; ++ int err = 0; + + SMB_VFS_HANDLE_GET_DATA(handle, config, struct shadow_copy2_config, + return false); + + DEBUG(10, (__location__ ": enter path '%s'\n", name)); + ++ abs_path = make_path_absolute(mem_ctx, config, name); ++ if (abs_path == NULL) { ++ ret = false; ++ goto out; ++ } ++ name = abs_path; ++ ++ DEBUG(10, (__location__ ": abs path '%s'\n", name)); ++ ++ err = check_for_converted_path(mem_ctx, ++ handle, ++ config, ++ abs_path, ++ &already_converted, ++ psnappath); ++ if (err != 0) { ++ /* error in conversion. */ ++ ret = false; ++ goto out; ++ } ++ ++ if (already_converted) { ++ goto out; ++ } ++ ++ /* ++ * From here we're only looking to strip an ++ * SMB-layer @GMT- token. ++ */ ++ + p = strstr_m(name, "@GMT-"); + if (p == NULL) { + DEBUG(11, ("@GMT not found\n")); +- goto no_snapshot; ++ goto out; + } + if ((p > name) && (p[-1] != '/')) { + /* the GMT-token does not start a path-component */ + DEBUG(10, ("not at start, p=%p, name=%p, p[-1]=%d\n", + p, name, (int)p[-1])); +- goto no_snapshot; ++ goto out; + } + +- /* +- * Figure out whether we got an already converted string. One +- * case where this happens is in a smb2 create call with the +- * mxac create blob set. We do the get_acl call on +- * fsp->fsp_name, which is already converted. We are converted +- * if we got a file name of the form ".snapshots/@GMT-", +- * i.e. ".snapshots/" precedes "p". +- */ +- +- snapdir = lp_parm_const_string(SNUM(handle->conn), "shadow", "snapdir", +- ".snapshots"); +- snapdirlen = strlen(snapdir); + len_before_gmt = p - name; + +- if ((len_before_gmt >= (snapdirlen + 1)) && (p[-1] == '/')) { +- const char *parent_snapdir = p - (snapdirlen+1); +- +- DEBUG(10, ("parent_snapdir = %s\n", parent_snapdir)); +- +- if (strncmp(parent_snapdir, snapdir, snapdirlen) == 0) { +- DEBUG(10, ("name=%s is already converted\n", name)); +- goto no_snapshot; +- } +- } + q = strptime(p, GMT_FORMAT, &tm); + if (q == NULL) { + DEBUG(10, ("strptime failed\n")); +- goto no_snapshot; ++ goto out; + } + tm.tm_isdst = -1; + timestamp = timegm(&tm); + if (timestamp == (time_t)-1) { + DEBUG(10, ("timestamp==-1\n")); +- goto no_snapshot; ++ goto out; + } + if (q[0] == '\0') { + /* +@@ -456,14 +477,33 @@ static bool shadow_copy2_strip_snapshot_internal(TALLOC_CTX *mem_ctx, + * with a path prefix. + */ + if (pstripped != NULL) { ++ if (len_before_gmt > 0) { ++ /* ++ * There is a slash before ++ * the @GMT-. Remove it. ++ */ ++ len_before_gmt -= 1; ++ } + stripped = talloc_strndup(mem_ctx, name, p - name); + if (stripped == NULL) { +- return false; ++ ret = false; ++ goto out; ++ } ++ if (orig_name[0] != '/') { ++ if (make_relative_path(config->shadow_cwd, ++ stripped) == false) { ++ DEBUG(10, (__location__ ": path '%s' " ++ "doesn't start with cwd '%s\n", ++ stripped, config->shadow_cwd)); ++ ret = false; ++ errno = ENOENT; ++ goto out; ++ } + } + *pstripped = stripped; + } + *ptimestamp = timestamp; +- return true; ++ goto out; + } + if (q[0] != '/') { + /* +@@ -471,75 +511,18 @@ static bool shadow_copy2_strip_snapshot_internal(TALLOC_CTX *mem_ctx, + * component continues after the gmt-token. + */ + DEBUG(10, ("q[0] = %d\n", (int)q[0])); +- goto no_snapshot; ++ goto out; + } + q += 1; + + rest_len = strlen(q); + dst_len = (p-name) + rest_len; + +- if (config->snapdirseverywhere) { +- char *insert; +- bool have_insert; +- insert = shadow_copy2_insert_string(talloc_tos(), handle, +- timestamp); +- if (insert == NULL) { +- errno = ENOMEM; +- return false; +- } +- +- DEBUG(10, (__location__ ": snapdirseverywhere mode.\n" +- "path '%s'.\n" +- "insert string '%s'\n", name, insert)); +- +- have_insert = (strstr(name, insert+1) != NULL); +- DEBUG(10, ("have_insert=%d, name=%s, insert+1=%s\n", +- (int)have_insert, name, insert+1)); +- if (have_insert) { +- DEBUG(10, (__location__ ": insert string '%s' found in " +- "path '%s' found in snapdirseverywhere mode " +- "==> already converted\n", insert, name)); +- TALLOC_FREE(insert); +- goto no_snapshot; +- } +- TALLOC_FREE(insert); +- } else { +- char *snapshot_path; +- char *s; +- +- snapshot_path = shadow_copy2_snapshot_path(talloc_tos(), +- handle, +- timestamp); +- if (snapshot_path == NULL) { +- errno = ENOMEM; +- return false; +- } +- +- DEBUG(10, (__location__ " path: '%s'.\n" +- "snapshot path: '%s'\n", name, snapshot_path)); +- +- s = strstr(name, snapshot_path); +- if (s == name) { +- /* +- * this starts with "snapshot_basepath/GMT-Token" +- * so it is already a converted absolute +- * path. Don't process further. +- */ +- DEBUG(10, (__location__ ": path '%s' starts with " +- "snapshot path '%s' (not in " +- "snapdirseverywhere mode) ==> " +- "already converted\n", name, snapshot_path)); +- talloc_free(snapshot_path); +- goto no_snapshot; +- } +- talloc_free(snapshot_path); +- } +- + if (pstripped != NULL) { + stripped = talloc_array(mem_ctx, char, dst_len+1); + if (stripped == NULL) { +- errno = ENOMEM; +- return false; ++ ret = false; ++ goto out; + } + if (p > name) { + memcpy(stripped, name, p-name); +@@ -548,13 +531,25 @@ static bool shadow_copy2_strip_snapshot_internal(TALLOC_CTX *mem_ctx, + memcpy(stripped + (p-name), q, rest_len); + } + stripped[dst_len] = '\0'; ++ if (orig_name[0] != '/') { ++ if (make_relative_path(config->shadow_cwd, ++ stripped) == false) { ++ DEBUG(10, (__location__ ": path '%s' " ++ "doesn't start with cwd '%s\n", ++ stripped, config->shadow_cwd)); ++ ret = false; ++ errno = ENOENT; ++ goto out; ++ } ++ } + *pstripped = stripped; + } + *ptimestamp = timestamp; +- return true; +-no_snapshot: +- *ptimestamp = 0; +- return true; ++ ret = true; ++ ++ out: ++ TALLOC_FREE(abs_path); ++ return ret; + } + + static bool shadow_copy2_strip_snapshot(TALLOC_CTX *mem_ctx, +-- +1.9.1 + diff -Nru samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-18.patch samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-18.patch --- samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-18.patch 1970-01-01 00:00:00.000000000 +0000 +++ samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-18.patch 2017-03-16 12:59:12.000000000 +0000 @@ -0,0 +1,64 @@ +From 79c2349c2d57068a34356918a8db285515a23812 Mon Sep 17 00:00:00 2001 +From: Jeremy Allison +Date: Mon, 23 Jan 2017 10:06:44 -0800 +Subject: [PATCH] s3: VFS: shadow_copy2: Fix a memory leak in the connectpath + function. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12531 + +Signed-off-by: Jeremy Allison +Reviewed-by: Uri Simchoni +(backported from commit 4d339a88851f601fae195ac8ff0691cbd3504f41) +--- + source3/modules/vfs_shadow_copy2.c | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +Index: samba-4.4.5+dfsg/source3/modules/vfs_shadow_copy2.c +=================================================================== +--- samba-4.4.5+dfsg.orig/source3/modules/vfs_shadow_copy2.c 2017-03-16 08:59:10.275327700 -0400 ++++ samba-4.4.5+dfsg/source3/modules/vfs_shadow_copy2.c 2017-03-16 08:59:10.271327653 -0400 +@@ -52,6 +52,8 @@ + char *shadow_cwd; /* Absolute $cwd path. */ + /* Absolute connectpath - can vary depending on $cwd. */ + char *shadow_connectpath; ++ /* malloc'ed realpath return. */ ++ char *shadow_realpath; + }; + + static bool shadow_copy2_find_slashes(TALLOC_CTX *mem_ctx, const char *str, +@@ -2058,6 +2060,13 @@ + goto done; + } + ++ /* ++ * SMB_VFS_NEXT_REALPATH returns a malloc'ed string. ++ * Don't leak memory. ++ */ ++ SAFE_FREE(config->shadow_realpath); ++ config->shadow_realpath = result; ++ + DBG_DEBUG("connect path is [%s]\n", result); + + done: +@@ -2135,6 +2144,12 @@ + return ret; + } + ++static int shadow_copy2_config_destructor(struct shadow_copy2_config *config) ++{ ++ SAFE_FREE(config->shadow_realpath); ++ return 0; ++} ++ + static int shadow_copy2_connect(struct vfs_handle_struct *handle, + const char *service, const char *user) + { +@@ -2163,6 +2178,8 @@ + return -1; + } + ++ talloc_set_destructor(config, shadow_copy2_config_destructor); ++ + gmt_format = lp_parm_const_string(SNUM(handle->conn), + "shadow", "format", + GMT_FORMAT); diff -Nru samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-19.patch samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-19.patch --- samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-19.patch 1970-01-01 00:00:00.000000000 +0000 +++ samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-19.patch 2017-03-16 13:01:06.000000000 +0000 @@ -0,0 +1,699 @@ +Backport of: + +From eeef5e408ba03815cf175539f5c83c34cb05aa24 Mon Sep 17 00:00:00 2001 +From: Jeremy Allison +Date: Mon, 23 Jan 2017 10:20:13 -0800 +Subject: [PATCH] s3: VFS: shadow_copy2: Fix usage of saved_errno to only set + errno on error. + +Rationale: + +VFS calls must act like their POSIX equivalents, and the POSIX versions +*only* set errno on a failure. There is actually code in the upper smbd +layers that depends on errno being correct on a fail return from a VFS call. + +For a compound VFS module like this, a common pattern is : + +SMB_VFS_CALL_X() +{ + int ret; + + syscall1(); + ret = syscall2(); + syscall3(); + + return ret; +} + +Where if *any* of the contained syscallX()'s fail, they'll set errno. +However, the actual errno we should return is *only* the one returned +if syscall2() fails (the others are lstat's checking for existence etc.). + +So what we should do to correctly return only the errno from syscall2() is: + +SMB_VFS_CALL_X() +{ + int ret; + int saved_errno = 0; + + syscall1() + + ret = syscall2(); + if (ret == -1) { + saved_errno = errno; + } + syscall3() + + if (saved_errno != 0) { + errno = saved_errno; + } + return ret; +} + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12531 + +Signed-off-by: Jeremy Allison +Reviewed-by: Uri Simchoni +(backported from commit cda6764f1a8db96182bfd1855440bc6a1ba1abee) +--- + source3/modules/vfs_shadow_copy2.c | 254 ++++++++++++++++++++++++++----------- + 1 file changed, 182 insertions(+), 72 deletions(-) + +Index: samba-4.4.5+dfsg/source3/modules/vfs_shadow_copy2.c +=================================================================== +--- samba-4.4.5+dfsg.orig/source3/modules/vfs_shadow_copy2.c 2017-03-16 08:59:43.535715820 -0400 ++++ samba-4.4.5+dfsg/source3/modules/vfs_shadow_copy2.c 2017-03-16 09:00:41.776394964 -0400 +@@ -619,7 +619,8 @@ + char *insert = NULL; + char *converted = NULL; + size_t insertlen, connectlen = 0; +- int i, saved_errno; ++ int saved_errno = 0; ++ int i; + size_t min_offset; + struct shadow_copy2_config *config; + size_t in_share_offset = 0; +@@ -802,12 +803,16 @@ + errno = ENOENT; + } + fail: +- saved_errno = errno; ++ if (result == NULL) { ++ saved_errno = errno; ++ } + TALLOC_FREE(converted); + TALLOC_FREE(insert); + TALLOC_FREE(slashes); + TALLOC_FREE(path); +- errno = saved_errno; ++ if (saved_errno != 0) { ++ errno = saved_errno; ++ } + return result; + } + +@@ -866,7 +871,7 @@ + time_t timestamp = 0; + char *stripped = NULL; + DIR *ret; +- int saved_errno; ++ int saved_errno = 0; + char *conv; + + if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, fname, +@@ -882,9 +887,13 @@ + return NULL; + } + ret = SMB_VFS_NEXT_OPENDIR(handle, conv, mask, attr); +- saved_errno = errno; ++ if (ret == NULL) { ++ saved_errno = errno; ++ } + TALLOC_FREE(conv); +- errno = saved_errno; ++ if (saved_errno != 0) { ++ errno = saved_errno; ++ } + return ret; + } + +@@ -964,7 +973,8 @@ + time_t timestamp = 0; + char *stripped = NULL; + char *tmp; +- int ret, saved_errno; ++ int saved_errno = 0; ++ int ret; + + if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, + smb_fname->base_name, +@@ -986,7 +996,9 @@ + } + + ret = SMB_VFS_NEXT_STAT(handle, smb_fname); +- saved_errno = errno; ++ if (ret == -1) { ++ saved_errno = errno; ++ } + + TALLOC_FREE(smb_fname->base_name); + smb_fname->base_name = tmp; +@@ -994,7 +1006,9 @@ + if (ret == 0) { + convert_sbuf(handle, smb_fname->base_name, &smb_fname->st); + } +- errno = saved_errno; ++ if (saved_errno != 0) { ++ errno = saved_errno; ++ } + return ret; + } + +@@ -1004,7 +1018,8 @@ + time_t timestamp = 0; + char *stripped = NULL; + char *tmp; +- int ret, saved_errno; ++ int saved_errno = 0; ++ int ret; + + if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, + smb_fname->base_name, +@@ -1026,7 +1041,9 @@ + } + + ret = SMB_VFS_NEXT_LSTAT(handle, smb_fname); +- saved_errno = errno; ++ if (ret == -1) { ++ saved_errno = errno; ++ } + + TALLOC_FREE(smb_fname->base_name); + smb_fname->base_name = tmp; +@@ -1034,7 +1051,9 @@ + if (ret == 0) { + convert_sbuf(handle, smb_fname->base_name, &smb_fname->st); + } +- errno = saved_errno; ++ if (saved_errno != 0) { ++ errno = saved_errno; ++ } + return ret; + } + +@@ -1066,7 +1085,8 @@ + time_t timestamp = 0; + char *stripped = NULL; + char *tmp; +- int ret, saved_errno; ++ int saved_errno = 0; ++ int ret; + + if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, + smb_fname->base_name, +@@ -1088,12 +1108,16 @@ + } + + ret = SMB_VFS_NEXT_OPEN(handle, smb_fname, fsp, flags, mode); +- saved_errno = errno; ++ if (ret == -1) { ++ saved_errno = errno; ++ } + + TALLOC_FREE(smb_fname->base_name); + smb_fname->base_name = tmp; + +- errno = saved_errno; ++ if (saved_errno != 0) { ++ errno = saved_errno; ++ } + return ret; + } + +@@ -1102,7 +1126,8 @@ + { + time_t timestamp = 0; + char *stripped = NULL; +- int ret, saved_errno; ++ int saved_errno = 0; ++ int ret; + struct smb_filename *conv; + + if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, +@@ -1125,9 +1150,13 @@ + return -1; + } + ret = SMB_VFS_NEXT_UNLINK(handle, conv); +- saved_errno = errno; ++ if (ret == -1) { ++ saved_errno = errno; ++ } + TALLOC_FREE(conv); +- errno = saved_errno; ++ if (saved_errno != 0) { ++ errno = saved_errno; ++ } + return ret; + } + +@@ -1136,7 +1165,8 @@ + { + time_t timestamp = 0; + char *stripped = NULL; +- int ret, saved_errno; ++ int saved_errno = 0; ++ int ret; + char *conv; + + if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, fname, +@@ -1152,9 +1182,13 @@ + return -1; + } + ret = SMB_VFS_NEXT_CHMOD(handle, conv, mode); +- saved_errno = errno; ++ if (ret == -1) { ++ saved_errno = errno; ++ } + TALLOC_FREE(conv); +- errno = saved_errno; ++ if (saved_errno != 0) { ++ errno = saved_errno; ++ } + return ret; + } + +@@ -1163,7 +1197,8 @@ + { + time_t timestamp = 0; + char *stripped = NULL; +- int ret, saved_errno; ++ int saved_errno = 0; ++ int ret; + char *conv; + + if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, fname, +@@ -1179,9 +1214,13 @@ + return -1; + } + ret = SMB_VFS_NEXT_CHOWN(handle, conv, uid, gid); +- saved_errno = errno; ++ if (ret == -1) { ++ saved_errno = errno; ++ } + TALLOC_FREE(conv); +- errno = saved_errno; ++ if (saved_errno != 0) { ++ errno = saved_errno; ++ } + return ret; + } + +@@ -1273,7 +1312,8 @@ + { + time_t timestamp = 0; + char *stripped = NULL; +- int ret, saved_errno; ++ int saved_errno = 0; ++ int ret; + struct smb_filename *conv; + + if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, +@@ -1296,9 +1336,13 @@ + return -1; + } + ret = SMB_VFS_NEXT_NTIMES(handle, conv, ft); +- saved_errno = errno; ++ if (ret == -1) { ++ saved_errno = errno; ++ } + TALLOC_FREE(conv); +- errno = saved_errno; ++ if (saved_errno != 0) { ++ errno = saved_errno; ++ } + return ret; + } + +@@ -1307,7 +1351,8 @@ + { + time_t timestamp = 0; + char *stripped = NULL; +- int ret, saved_errno; ++ int saved_errno = 0; ++ int ret; + char *conv; + + if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, fname, +@@ -1323,9 +1368,13 @@ + return -1; + } + ret = SMB_VFS_NEXT_READLINK(handle, conv, buf, bufsiz); +- saved_errno = errno; ++ if (ret == -1) { ++ saved_errno = errno; ++ } + TALLOC_FREE(conv); +- errno = saved_errno; ++ if (saved_errno != 0) { ++ errno = saved_errno; ++ } + return ret; + } + +@@ -1334,7 +1383,8 @@ + { + time_t timestamp = 0; + char *stripped = NULL; +- int ret, saved_errno; ++ int saved_errno = 0; ++ int ret; + char *conv; + + if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, fname, +@@ -1350,9 +1400,13 @@ + return -1; + } + ret = SMB_VFS_NEXT_MKNOD(handle, conv, mode, dev); +- saved_errno = errno; ++ if (ret == -1) { ++ saved_errno = errno; ++ } + TALLOC_FREE(conv); +- errno = saved_errno; ++ if (saved_errno != 0) { ++ errno = saved_errno; ++ } + return ret; + } + +@@ -1363,7 +1417,7 @@ + char *stripped = NULL; + char *tmp = NULL; + char *result = NULL; +- int saved_errno; ++ int saved_errno = 0; + + if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, fname, + ×tamp, &stripped)) { +@@ -1381,10 +1435,14 @@ + result = SMB_VFS_NEXT_REALPATH(handle, tmp); + + done: +- saved_errno = errno; ++ if (result == NULL) { ++ saved_errno = errno; ++ } + TALLOC_FREE(tmp); + TALLOC_FREE(stripped); +- errno = saved_errno; ++ if (saved_errno != 0) { ++ errno = saved_errno; ++ } + return result; + } + +@@ -1753,7 +1811,8 @@ + { + time_t timestamp = 0; + char *stripped = NULL; +- int ret, saved_errno; ++ int saved_errno = 0; ++ int ret; + char *conv; + + if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, fname, +@@ -1769,9 +1828,13 @@ + return -1; + } + ret = SMB_VFS_NEXT_MKDIR(handle, conv, mode); +- saved_errno = errno; ++ if (ret == -1) { ++ saved_errno = errno; ++ } + TALLOC_FREE(conv); +- errno = saved_errno; ++ if (saved_errno != 0) { ++ errno = saved_errno; ++ } + return ret; + } + +@@ -1779,7 +1842,8 @@ + { + time_t timestamp = 0; + char *stripped = NULL; +- int ret, saved_errno; ++ int saved_errno = 0; ++ int ret; + char *conv; + + if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, fname, +@@ -1795,9 +1859,13 @@ + return -1; + } + ret = SMB_VFS_NEXT_RMDIR(handle, conv); +- saved_errno = errno; ++ if (ret == -1) { ++ saved_errno = errno; ++ } + TALLOC_FREE(conv); +- errno = saved_errno; ++ if (saved_errno != 0) { ++ errno = saved_errno; ++ } + return ret; + } + +@@ -1806,7 +1874,8 @@ + { + time_t timestamp = 0; + char *stripped = NULL; +- int ret, saved_errno; ++ int saved_errno = 0; ++ int ret; + char *conv; + + if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, fname, +@@ -1822,9 +1891,13 @@ + return -1; + } + ret = SMB_VFS_NEXT_CHFLAGS(handle, conv, flags); +- saved_errno = errno; ++ if (ret == -1) { ++ saved_errno = errno; ++ } + TALLOC_FREE(conv); +- errno = saved_errno; ++ if (saved_errno != 0) { ++ errno = saved_errno; ++ } + return ret; + } + +@@ -1835,7 +1908,7 @@ + time_t timestamp = 0; + char *stripped = NULL; + ssize_t ret; +- int saved_errno; ++ int saved_errno = 0; + char *conv; + + if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, fname, +@@ -1852,9 +1925,13 @@ + return -1; + } + ret = SMB_VFS_NEXT_GETXATTR(handle, conv, aname, value, size); +- saved_errno = errno; ++ if (ret == -1) { ++ saved_errno = errno; ++ } + TALLOC_FREE(conv); +- errno = saved_errno; ++ if (saved_errno != 0) { ++ errno = saved_errno; ++ } + return ret; + } + +@@ -1865,7 +1942,7 @@ + time_t timestamp = 0; + char *stripped = NULL; + ssize_t ret; +- int saved_errno; ++ int saved_errno = 0; + char *conv; + + if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, fname, +@@ -1881,9 +1958,13 @@ + return -1; + } + ret = SMB_VFS_NEXT_LISTXATTR(handle, conv, list, size); +- saved_errno = errno; ++ if (ret == -1) { ++ saved_errno = errno; ++ } + TALLOC_FREE(conv); +- errno = saved_errno; ++ if (saved_errno != 0) { ++ errno = saved_errno; ++ } + return ret; + } + +@@ -1892,7 +1973,8 @@ + { + time_t timestamp = 0; + char *stripped = NULL; +- int ret, saved_errno; ++ int saved_errno = 0; ++ int ret; + char *conv; + + if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, fname, +@@ -1908,9 +1990,13 @@ + return -1; + } + ret = SMB_VFS_NEXT_REMOVEXATTR(handle, conv, aname); +- saved_errno = errno; ++ if (ret == -1) { ++ saved_errno = errno; ++ } + TALLOC_FREE(conv); +- errno = saved_errno; ++ if (saved_errno != 0) { ++ errno = saved_errno; ++ } + return ret; + } + +@@ -1922,7 +2008,7 @@ + time_t timestamp = 0; + char *stripped = NULL; + ssize_t ret; +- int saved_errno; ++ int saved_errno = 0; + char *conv; + + if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, fname, +@@ -1939,9 +2025,13 @@ + return -1; + } + ret = SMB_VFS_NEXT_SETXATTR(handle, conv, aname, value, size, flags); +- saved_errno = errno; ++ if (ret == -1) { ++ saved_errno = errno; ++ } + TALLOC_FREE(conv); +- errno = saved_errno; ++ if (saved_errno != 0) { ++ errno = saved_errno; ++ } + return ret; + } + +@@ -1951,7 +2041,7 @@ + time_t timestamp = 0; + char *stripped = NULL; + ssize_t ret; +- int saved_errno; ++ int saved_errno = 0; + char *conv; + + if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, fname, +@@ -1967,9 +2057,13 @@ + return -1; + } + ret = SMB_VFS_NEXT_CHMOD_ACL(handle, conv, mode); +- saved_errno = errno; ++ if (ret == -1) { ++ saved_errno = errno; ++ } + TALLOC_FREE(conv); +- errno = saved_errno; ++ if (saved_errno != 0) { ++ errno = saved_errno; ++ } + return ret; + } + +@@ -1982,7 +2076,7 @@ + time_t timestamp = 0; + char *stripped = NULL; + ssize_t ret; +- int saved_errno; ++ int saved_errno = 0; + char *conv; + + DEBUG(10, ("shadow_copy2_get_real_filename called for path=[%s], " +@@ -2009,9 +2103,13 @@ + ret = SMB_VFS_NEXT_GET_REAL_FILENAME(handle, conv, name, + mem_ctx, found_name); + DEBUG(10, ("NEXT_REAL_FILE_NAME returned %d\n", (int)ret)); +- saved_errno = errno; ++ if (ret == -1) { ++ saved_errno = errno; ++ } + TALLOC_FREE(conv); +- errno = saved_errno; ++ if (saved_errno != 0) { ++ errno = saved_errno; ++ } + return ret; + } + +@@ -2022,7 +2120,7 @@ + char *stripped = NULL; + char *tmp = NULL; + char *result = NULL; +- int saved_errno; ++ int saved_errno = 0; + size_t rootpath_len = 0; + struct shadow_copy2_config *config = NULL; + +@@ -2070,10 +2168,14 @@ + DBG_DEBUG("connect path is [%s]\n", result); + + done: +- saved_errno = errno; ++ if (result == NULL) { ++ saved_errno = errno; ++ } + TALLOC_FREE(tmp); + TALLOC_FREE(stripped); +- errno = saved_errno; ++ if (saved_errno != 0) { ++ errno = saved_errno; ++ } + return result; + } + +@@ -2084,7 +2186,7 @@ + time_t timestamp = 0; + char *stripped = NULL; + ssize_t ret; +- int saved_errno; ++ int saved_errno = 0; + char *conv; + + if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, path, +@@ -2104,9 +2206,13 @@ + + ret = SMB_VFS_NEXT_DISK_FREE(handle, conv, bsize, dfree, dsize); + +- saved_errno = errno; ++ if (ret == -1) { ++ saved_errno = errno; ++ } + TALLOC_FREE(conv); +- errno = saved_errno; ++ if (saved_errno != 0) { ++ errno = saved_errno; ++ } + + return ret; + } +@@ -2118,7 +2224,7 @@ + time_t timestamp = 0; + char *stripped = NULL; + int ret; +- int saved_errno; ++ int saved_errno = 0; + char *conv; + + if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, path, ×tamp, +@@ -2137,9 +2243,13 @@ + + ret = SMB_VFS_NEXT_GET_QUOTA(handle, conv, qtype, id, dq); + +- saved_errno = errno; ++ if (ret == -1) { ++ saved_errno = errno; ++ } + TALLOC_FREE(conv); +- errno = saved_errno; ++ if (saved_errno != 0) { ++ errno = saved_errno; ++ } + + return ret; + } diff -Nru samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-1.patch samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-1.patch --- samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-1.patch 1970-01-01 00:00:00.000000000 +0000 +++ samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-1.patch 2017-03-16 12:57:04.000000000 +0000 @@ -0,0 +1,195 @@ +From e3816bb04a761202747a73f282e193cb294c41e1 Mon Sep 17 00:00:00 2001 +From: Jeremy Allison +Date: Wed, 11 Jan 2017 16:30:38 -0800 +Subject: [PATCH] s3: smbd: Correctly canonicalize any incoming shadow copy + path. + +Converts to: + +@GMT-token/path/last_component + +from all incoming path types. Allows shadow_copy modules +to work when current directory is changed after removing +last component. + +Ultimately when the VFS ABI is changed to add a timestamp +to struct smb_filename, this is where the parsing will be +done. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12531 + +Signed-off-by: Jeremy Allison +Reviewed-by: Uri Simchoni +(backported from commit 39678ed6af708fb6f2760bfb51051add11e3c498) +--- + source3/smbd/filename.c | 150 ++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 150 insertions(+) + +Index: samba-4.4.5+dfsg/source3/smbd/filename.c +=================================================================== +--- samba-4.4.5+dfsg.orig/source3/smbd/filename.c 2017-03-16 08:57:02.165830886 -0400 ++++ samba-4.4.5+dfsg/source3/smbd/filename.c 2017-03-16 08:57:02.165830886 -0400 +@@ -197,6 +197,148 @@ + return NT_STATUS_OK; + } + ++/* ++ * Re-order a known good @GMT-token path. ++ */ ++ ++static NTSTATUS rearrange_snapshot_path(struct smb_filename *smb_fname, ++ char *startp, ++ char *endp) ++{ ++ size_t endlen = 0; ++ size_t gmt_len = endp - startp; ++ char gmt_store[gmt_len + 1]; ++ char *parent = NULL; ++ const char *last_component = NULL; ++ char *newstr; ++ bool ret; ++ ++ DBG_DEBUG("|%s| -> ", smb_fname->base_name); ++ ++ /* Save off the @GMT-token. */ ++ memcpy(gmt_store, startp, gmt_len); ++ gmt_store[gmt_len] = '\0'; ++ ++ if (*endp == '/') { ++ /* Remove any trailing '/' */ ++ endp++; ++ } ++ ++ if (*endp == '\0') { ++ /* ++ * @GMT-token was at end of path. ++ * Remove any preceeding '/' ++ */ ++ if (startp > smb_fname->base_name && startp[-1] == '/') { ++ startp--; ++ } ++ } ++ ++ /* Remove @GMT-token from the path. */ ++ endlen = strlen(endp); ++ memmove(startp, endp, endlen + 1); ++ ++ /* Split the remaining path into components. */ ++ ret = parent_dirname(smb_fname, ++ smb_fname->base_name, ++ &parent, ++ &last_component); ++ if (ret == false) { ++ /* Must terminate debug with \n */ ++ DBG_DEBUG("NT_STATUS_NO_MEMORY\n"); ++ return NT_STATUS_NO_MEMORY; ++ } ++ ++ if (ISDOT(parent)) { ++ if (last_component[0] == '\0') { ++ newstr = talloc_strdup(smb_fname, ++ gmt_store); ++ } else { ++ newstr = talloc_asprintf(smb_fname, ++ "%s/%s", ++ gmt_store, ++ last_component); ++ } ++ } else { ++ newstr = talloc_asprintf(smb_fname, ++ "%s/%s/%s", ++ gmt_store, ++ parent, ++ last_component); ++ } ++ ++ TALLOC_FREE(parent); ++ TALLOC_FREE(smb_fname->base_name); ++ smb_fname->base_name = newstr; ++ ++ DBG_DEBUG("|%s|\n", newstr); ++ ++ return NT_STATUS_OK; ++} ++ ++/* ++ * Canonicalize any incoming pathname potentially containining ++ * a @GMT-token into a path that looks like: ++ * ++ * @GMT-YYYY-MM-DD-HH-MM-SS/path/name/components/last_component ++ * ++ * Leaves single path @GMT-token -component alone: ++ * ++ * @GMT-YYYY-MM-DD-HH-MM-SS -> @GMT-YYYY-MM-DD-HH-MM-SS ++ * ++ * Eventually when struct smb_filename is updated and the VFS ++ * ABI is changed this will remove the @GMT-YYYY-MM-DD-HH-MM-SS ++ * and store in the struct smb_filename as a struct timeval field ++ * instead. ++ */ ++ ++static NTSTATUS canonicalize_snapshot_path(struct smb_filename *smb_fname) ++{ ++ char *startp = strchr_m(smb_fname->base_name, '@'); ++ char *endp = NULL; ++ struct tm tm; ++ ++ if (startp == NULL) { ++ /* No @ */ ++ return NT_STATUS_OK; ++ } ++ ++ startp = strstr_m(startp, "@GMT-"); ++ if (startp == NULL) { ++ /* No @ */ ++ return NT_STATUS_OK; ++ } ++ ++ if ((startp > smb_fname->base_name) && (startp[-1] != '/')) { ++ /* the GMT-token does not start a path-component */ ++ return NT_STATUS_OK; ++ } ++ ++ endp = strptime(startp, GMT_FORMAT, &tm); ++ if (endp == NULL) { ++ /* Not a valid timestring. */ ++ return NT_STATUS_OK; ++ } ++ ++ if ( endp[0] == '\0') { ++ return rearrange_snapshot_path(smb_fname, ++ startp, ++ endp); ++ } ++ ++ if (endp[0] != '/') { ++ /* ++ * It is not a complete path component, i.e. the path ++ * component continues after the gmt-token. ++ */ ++ return NT_STATUS_OK; ++ } ++ ++ return rearrange_snapshot_path(smb_fname, ++ startp, ++ endp); ++} ++ + /**************************************************************************** + This routine is called to convert names from the dos namespace to unix + namespace. It needs to handle any case conversions, mangling, format changes, +@@ -331,6 +473,14 @@ + goto err; + } + ++ /* Canonicalize any @GMT- paths. */ ++ if (posix_pathnames == false) { ++ status = canonicalize_snapshot_path(smb_fname); ++ if (!NT_STATUS_IS_OK(status)) { ++ goto err; ++ } ++ } ++ + /* + * Large directory fix normalization. If we're case sensitive, and + * the case preserving parameters are set to "no", normalize the case of diff -Nru samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-20.patch samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-20.patch --- samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-20.patch 1970-01-01 00:00:00.000000000 +0000 +++ samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-20.patch 2017-03-16 13:01:15.000000000 +0000 @@ -0,0 +1,134 @@ +From 81231afc2f968582fb1998b227713b34e74d9a7f Mon Sep 17 00:00:00 2001 +From: Jeremy Allison +Date: Thu, 26 Jan 2017 17:19:24 -0800 +Subject: [PATCH] s3: VFS: Don't allow symlink, link or rename on already + converted paths. + +Snapshot paths are a read-only filesystem. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12531 + +Signed-off-by: Jeremy Allison +Reviewed-by: Uri Simchoni + +Autobuild-User(master): Jeremy Allison +Autobuild-Date(master): Mon Jan 30 22:26:29 CET 2017 on sn-devel-144 + +(backported from commit 0e1deb77f2b310ad7e5dd784174207adacf1c981) +--- + source3/modules/vfs_shadow_copy2.c | 55 +++++++++++++++++++++++++++++--------- + 1 file changed, 43 insertions(+), 12 deletions(-) + +diff --git a/source3/modules/vfs_shadow_copy2.c b/source3/modules/vfs_shadow_copy2.c +index f773d4f..1345ca2 100644 +--- a/source3/modules/vfs_shadow_copy2.c ++++ b/source3/modules/vfs_shadow_copy2.c +@@ -903,15 +903,17 @@ static int shadow_copy2_rename(vfs_handle_struct *handle, + { + time_t timestamp_src = 0; + time_t timestamp_dst = 0; ++ char *snappath_src = NULL; ++ char *snappath_dst = NULL; + +- if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, ++ if (!shadow_copy2_strip_snapshot_internal(talloc_tos(), handle, + smb_fname_src->base_name, +- ×tamp_src, NULL)) { ++ ×tamp_src, NULL, &snappath_src)) { + return -1; + } +- if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, ++ if (!shadow_copy2_strip_snapshot_internal(talloc_tos(), handle, + smb_fname_dst->base_name, +- ×tamp_dst, NULL)) { ++ ×tamp_dst, NULL, &snappath_dst)) { + return -1; + } + if (timestamp_src != 0) { +@@ -922,6 +924,17 @@ static int shadow_copy2_rename(vfs_handle_struct *handle, + errno = EROFS; + return -1; + } ++ /* ++ * Don't allow rename on already converted paths. ++ */ ++ if (snappath_src != NULL) { ++ errno = EXDEV; ++ return -1; ++ } ++ if (snappath_dst != NULL) { ++ errno = EROFS; ++ return -1; ++ } + return SMB_VFS_NEXT_RENAME(handle, smb_fname_src, smb_fname_dst); + } + +@@ -930,19 +943,28 @@ static int shadow_copy2_symlink(vfs_handle_struct *handle, + { + time_t timestamp_old = 0; + time_t timestamp_new = 0; ++ char *snappath_old = NULL; ++ char *snappath_new = NULL; + +- if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, oldname, +- ×tamp_old, NULL)) { ++ if (!shadow_copy2_strip_snapshot_internal(talloc_tos(), handle, oldname, ++ ×tamp_old, NULL, &snappath_old)) { + return -1; + } +- if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, newname, +- ×tamp_new, NULL)) { ++ if (!shadow_copy2_strip_snapshot_internal(talloc_tos(), handle, newname, ++ ×tamp_new, NULL, &snappath_new)) { + return -1; + } + if ((timestamp_old != 0) || (timestamp_new != 0)) { + errno = EROFS; + return -1; + } ++ /* ++ * Don't allow symlinks on already converted paths. ++ */ ++ if ((snappath_old != NULL) || (snappath_new != NULL)) { ++ errno = EROFS; ++ return -1; ++ } + return SMB_VFS_NEXT_SYMLINK(handle, oldname, newname); + } + +@@ -951,19 +973,28 @@ static int shadow_copy2_link(vfs_handle_struct *handle, + { + time_t timestamp_old = 0; + time_t timestamp_new = 0; ++ char *snappath_old = NULL; ++ char *snappath_new = NULL; + +- if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, oldname, +- ×tamp_old, NULL)) { ++ if (!shadow_copy2_strip_snapshot_internal(talloc_tos(), handle, oldname, ++ ×tamp_old, NULL, &snappath_old)) { + return -1; + } +- if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, newname, +- ×tamp_new, NULL)) { ++ if (!shadow_copy2_strip_snapshot_internal(talloc_tos(), handle, newname, ++ ×tamp_new, NULL, &snappath_new)) { + return -1; + } + if ((timestamp_old != 0) || (timestamp_new != 0)) { + errno = EROFS; + return -1; + } ++ /* ++ * Don't allow links on already converted paths. ++ */ ++ if ((snappath_old != NULL) || (snappath_new != NULL)) { ++ errno = EROFS; ++ return -1; ++ } + return SMB_VFS_NEXT_LINK(handle, oldname, newname); + } + +-- +1.9.1 + diff -Nru samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-2.patch samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-2.patch --- samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-2.patch 1970-01-01 00:00:00.000000000 +0000 +++ samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-2.patch 2017-03-16 12:57:08.000000000 +0000 @@ -0,0 +1,175 @@ +From 38e2f4bf1b14e2ea514437e91bd1e34466094698 Mon Sep 17 00:00:00 2001 +From: Jeremy Allison +Date: Tue, 17 Jan 2017 11:33:18 -0800 +Subject: [PATCH] s3: lib: Add canonicalize_absolute_path(). + +Resolves any invalid path components (.) (..) +in an absolute POSIX path. + +We will be re-using this in several places. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12531 + +Signed-off-by: Jeremy Allison +Reviewed-by: Uri Simchoni +(backported from commit 02599c39337c3049762a6b0bd6290577817ee5a5) +--- + source3/lib/util_path.c | 133 ++++++++++++++++++++++++++++++++++++++++++++++++ + source3/lib/util_path.h | 1 + + 2 files changed, 134 insertions(+) + +diff --git a/source3/lib/util_path.c b/source3/lib/util_path.c +index 509ba5f..cbad2e1 100644 +--- a/source3/lib/util_path.c ++++ b/source3/lib/util_path.c +@@ -93,3 +93,136 @@ char *cache_path(const char *name) + { + return xx_path(name, lp_cache_directory()); + } ++ ++/** ++ * @brief Removes any invalid path components in an absolute POSIX path. ++ * ++ * @param ctx Talloc context to return string. ++ * ++ * @param abs_path Absolute path string to process. ++ * ++ * @retval Pointer to a talloc'ed string containing the absolute full path. ++ **/ ++ ++char *canonicalize_absolute_path(TALLOC_CTX *ctx, const char *abs_path) ++{ ++ char *destname; ++ char *d; ++ const char *s = abs_path; ++ bool start_of_name_component = true; ++ ++ /* Allocate for strlen + '\0' + possible leading '/' */ ++ destname = (char *)talloc_size(ctx, strlen(abs_path) + 2); ++ if (destname == NULL) { ++ return NULL; ++ } ++ d = destname; ++ ++ *d++ = '/'; /* Always start with root. */ ++ ++ while (*s) { ++ if (*s == '/') { ++ /* Eat multiple '/' */ ++ while (*s == '/') { ++ s++; ++ } ++ if ((d > destname + 1) && (*s != '\0')) { ++ *d++ = '/'; ++ } ++ start_of_name_component = true; ++ continue; ++ } ++ ++ if (start_of_name_component) { ++ if ((s[0] == '.') && (s[1] == '.') && ++ (s[2] == '/' || s[2] == '\0')) { ++ /* Uh oh - "/../" or "/..\0" ! */ ++ ++ /* Go past the ../ or .. */ ++ if (s[2] == '/') { ++ s += 3; ++ } else { ++ s += 2; /* Go past the .. */ ++ } ++ ++ /* If we just added a '/' - delete it */ ++ if ((d > destname) && (*(d-1) == '/')) { ++ *(d-1) = '\0'; ++ d--; ++ } ++ ++ /* ++ * Are we at the start ? ++ * Can't go back further if so. ++ */ ++ if (d <= destname) { ++ *d++ = '/'; /* Can't delete root */ ++ continue; ++ } ++ /* Go back one level... */ ++ /* ++ * Decrement d first as d points to ++ * the *next* char to write into. ++ */ ++ for (d--; d > destname; d--) { ++ if (*d == '/') { ++ break; ++ } ++ } ++ /* ++ * We're still at the start of a name ++ * component, just the previous one. ++ */ ++ continue; ++ } else if ((s[0] == '.') && ++ ((s[1] == '\0') || s[1] == '/')) { ++ /* ++ * Component of pathname can't be "." only. ++ * Skip the '.' . ++ */ ++ if (s[1] == '/') { ++ s += 2; ++ } else { ++ s++; ++ } ++ continue; ++ } ++ } ++ ++ if (!(*s & 0x80)) { ++ *d++ = *s++; ++ } else { ++ size_t siz; ++ /* Get the size of the next MB character. */ ++ next_codepoint(s,&siz); ++ switch(siz) { ++ case 5: ++ *d++ = *s++; ++ /*fall through*/ ++ case 4: ++ *d++ = *s++; ++ /*fall through*/ ++ case 3: ++ *d++ = *s++; ++ /*fall through*/ ++ case 2: ++ *d++ = *s++; ++ /*fall through*/ ++ case 1: ++ *d++ = *s++; ++ break; ++ default: ++ break; ++ } ++ } ++ start_of_name_component = false; ++ } ++ *d = '\0'; ++ ++ /* And must not end in '/' */ ++ if (d > destname + 1 && (*(d-1) == '/')) { ++ *(d-1) = '\0'; ++ } ++ ++ return destname; ++} +diff --git a/source3/lib/util_path.h b/source3/lib/util_path.h +index 118a4be..16e2792 100644 +--- a/source3/lib/util_path.h ++++ b/source3/lib/util_path.h +@@ -27,5 +27,6 @@ + char *lock_path(const char *name); + char *state_path(const char *name); + char *cache_path(const char *name); ++char *canonicalize_absolute_path(TALLOC_CTX *ctx, const char *abs_path); + + #endif +-- +1.9.1 + diff -Nru samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-3.patch samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-3.patch --- samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-3.patch 1970-01-01 00:00:00.000000000 +0000 +++ samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-3.patch 2017-03-16 12:57:13.000000000 +0000 @@ -0,0 +1,61 @@ +From 40f3664bfb86053d3550809f883793db54116b23 Mon Sep 17 00:00:00 2001 +From: Jeremy Allison +Date: Thu, 19 Jan 2017 15:18:41 -0800 +Subject: [PATCH] s3: lib: Fix two old, old bugs in set_conn_connectpath(), now + in canonicalize_absolute_path(). + +Canonicalizing a path of /foo/bar/../baz would return /foo/barbaz +as moving forward 3 characters would delete the / character. + +Canonicalizing /foo/.. would end up as '\0'. + +Test to follow. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12531 + +Signed-off-by: Jeremy Allison +Reviewed-by: Uri Simchoni +(backported from commit 82979afc46cc5e466bdd999a94080e7a5df95518) +--- + source3/lib/util_path.c | 18 ++++++++++++------ + 1 file changed, 12 insertions(+), 6 deletions(-) + +diff --git a/source3/lib/util_path.c b/source3/lib/util_path.c +index cbad2e1..6f58a03 100644 +--- a/source3/lib/util_path.c ++++ b/source3/lib/util_path.c +@@ -138,12 +138,8 @@ char *canonicalize_absolute_path(TALLOC_CTX *ctx, const char *abs_path) + (s[2] == '/' || s[2] == '\0')) { + /* Uh oh - "/../" or "/..\0" ! */ + +- /* Go past the ../ or .. */ +- if (s[2] == '/') { +- s += 3; +- } else { +- s += 2; /* Go past the .. */ +- } ++ /* Go past the .. leaving us on the / or '\0' */ ++ s += 2; + + /* If we just added a '/' - delete it */ + if ((d > destname) && (*(d-1) == '/')) { +@@ -169,6 +165,16 @@ char *canonicalize_absolute_path(TALLOC_CTX *ctx, const char *abs_path) + break; + } + } ++ ++ /* ++ * Are we at the start ? ++ * Can't go back further if so. ++ */ ++ if (d <= destname) { ++ *d++ = '/'; /* Can't delete root */ ++ continue; ++ } ++ + /* + * We're still at the start of a name + * component, just the previous one. +-- +1.9.1 + diff -Nru samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-4.patch samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-4.patch --- samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-4.patch 1970-01-01 00:00:00.000000000 +0000 +++ samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-4.patch 2017-03-16 12:57:20.000000000 +0000 @@ -0,0 +1,91 @@ +From 163234d5aec15f56648436a18073cac8368367a2 Mon Sep 17 00:00:00 2001 +From: Jeremy Allison +Date: Thu, 26 Jan 2017 16:08:42 -0800 +Subject: [PATCH] s3: smbtorture: Add new local test LOCAL-CANONICALIZE-PATH + +Tests new canonicalize_absolute_path() function. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12531 + +Signed-off-by: Jeremy Allison +Reviewed-by: Uri Simchoni +(backported from commit a51363309a4330b65e34ae941ec99d180bdbab56) +--- + source3/selftest/tests.py | 1 + + source3/torture/torture.c | 44 ++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 45 insertions(+) + +Index: samba-4.4.5+dfsg/source3/selftest/tests.py +=================================================================== +--- samba-4.4.5+dfsg.orig/source3/selftest/tests.py 2017-03-16 08:57:18.026016358 -0400 ++++ samba-4.4.5+dfsg/source3/selftest/tests.py 2017-03-16 08:57:18.022016312 -0400 +@@ -113,6 +113,7 @@ + "LOCAL-MESSAGING-FDPASS2", + "LOCAL-MESSAGING-FDPASS2a", + "LOCAL-MESSAGING-FDPASS2b", ++ "LOCAL-CANONICALIZE-PATH", + "LOCAL-hex_encode_buf", + "LOCAL-sprintf_append", + "LOCAL-remove_duplicate_addrs2"] +Index: samba-4.4.5+dfsg/source3/torture/torture.c +=================================================================== +--- samba-4.4.5+dfsg.orig/source3/torture/torture.c 2017-03-16 08:57:18.026016358 -0400 ++++ samba-4.4.5+dfsg/source3/torture/torture.c 2017-03-16 08:57:18.022016312 -0400 +@@ -9878,6 +9878,49 @@ + return true; + } + ++static bool run_local_canonicalize_path(int dummy) ++{ ++ const char *src[] = { ++ "/foo/..", ++ "/..", ++ "/foo/bar/../baz", ++ "/foo/././", ++ "/../foo", ++ ".././././", ++ ".././././../../../boo", ++ "./..", ++ NULL ++ }; ++ const char *dst[] = { ++ "/", ++ "/", ++ "/foo/baz", ++ "/foo", ++ "/foo", ++ "/", ++ "/boo", ++ "/", ++ NULL ++ }; ++ unsigned int i; ++ ++ for (i = 0; src[i] != NULL; i++) { ++ char *d = canonicalize_absolute_path(talloc_tos(), src[i]); ++ if (d == NULL) { ++ perror("talloc fail\n"); ++ return false; ++ } ++ if (strcmp(d, dst[i]) != 0) { ++ d_fprintf(stderr, ++ "canonicalize missmatch %s -> %s != %s", ++ src[i], d, dst[i]); ++ return false; ++ } ++ talloc_free(d); ++ } ++ return true; ++} ++ + static double create_procs(bool (*fn)(int), bool *result) + { + int i, status; +@@ -10107,6 +10150,7 @@ + { "local-tdb-writer", run_local_tdb_writer, 0 }, + { "LOCAL-DBWRAP-CTDB", run_local_dbwrap_ctdb, 0 }, + { "LOCAL-BENCH-PTHREADPOOL", run_bench_pthreadpool, 0 }, ++ { "LOCAL-CANONICALIZE-PATH", run_local_canonicalize_path, 0 }, + { "qpathinfo-bufsize", run_qpathinfo_bufsize, 0 }, + {NULL, NULL, 0}}; + diff -Nru samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-5.patch samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-5.patch --- samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-5.patch 1970-01-01 00:00:00.000000000 +0000 +++ samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-5.patch 2017-03-16 12:57:23.000000000 +0000 @@ -0,0 +1,151 @@ +From f9edf3e0c9561a4198b93f81742e4c8ec35b8e6d Mon Sep 17 00:00:00 2001 +From: Jeremy Allison +Date: Tue, 17 Jan 2017 11:35:52 -0800 +Subject: [PATCH] s3: smbd: Make set_conn_connectpath() call + canonicalize_absolute_path(). + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12531 + +Signed-off-by: Jeremy Allison +Reviewed-by: Uri Simchoni +(backported from commit d650d65488761b30fa34d42cb1ab400618a78c33) +--- + source3/smbd/service.c | 103 ++----------------------------------------------- + 1 file changed, 3 insertions(+), 100 deletions(-) + +diff --git a/source3/smbd/service.c b/source3/smbd/service.c +index 8c6d140..2702a24 100644 +--- a/source3/smbd/service.c ++++ b/source3/smbd/service.c +@@ -31,6 +31,7 @@ + #include "lib/param/loadparm.h" + #include "messages.h" + #include "lib/afs/afs_funcs.h" ++#include "lib/util_path.h" + + static bool canonicalize_connect_path(connection_struct *conn) + { +@@ -47,118 +48,20 @@ static bool canonicalize_connect_path(connection_struct *conn) + /**************************************************************************** + Ensure when setting connectpath it is a canonicalized (no ./ // or ../) + absolute path stating in / and not ending in /. +- Observent people will notice a similarity between this and check_path_syntax :-). + ****************************************************************************/ + + bool set_conn_connectpath(connection_struct *conn, const char *connectpath) + { + char *destname; +- char *d; +- const char *s = connectpath; +- bool start_of_name_component = true; + + if (connectpath == NULL || connectpath[0] == '\0') { + return false; + } + +- /* Allocate for strlen + '\0' + possible leading '/' */ +- destname = (char *)talloc_size(conn, strlen(connectpath) + 2); +- if (!destname) { ++ destname = canonicalize_absolute_path(conn, connectpath); ++ if (destname == NULL) { + return false; + } +- d = destname; +- +- *d++ = '/'; /* Always start with root. */ +- +- while (*s) { +- if (*s == '/') { +- /* Eat multiple '/' */ +- while (*s == '/') { +- s++; +- } +- if ((d > destname + 1) && (*s != '\0')) { +- *d++ = '/'; +- } +- start_of_name_component = True; +- continue; +- } +- +- if (start_of_name_component) { +- if ((s[0] == '.') && (s[1] == '.') && (s[2] == '/' || s[2] == '\0')) { +- /* Uh oh - "/../" or "/..\0" ! */ +- +- /* Go past the ../ or .. */ +- if (s[2] == '/') { +- s += 3; +- } else { +- s += 2; /* Go past the .. */ +- } +- +- /* If we just added a '/' - delete it */ +- if ((d > destname) && (*(d-1) == '/')) { +- *(d-1) = '\0'; +- d--; +- } +- +- /* Are we at the start ? Can't go back further if so. */ +- if (d <= destname) { +- *d++ = '/'; /* Can't delete root */ +- continue; +- } +- /* Go back one level... */ +- /* Decrement d first as d points to the *next* char to write into. */ +- for (d--; d > destname; d--) { +- if (*d == '/') { +- break; +- } +- } +- /* We're still at the start of a name component, just the previous one. */ +- continue; +- } else if ((s[0] == '.') && ((s[1] == '\0') || s[1] == '/')) { +- /* Component of pathname can't be "." only - skip the '.' . */ +- if (s[1] == '/') { +- s += 2; +- } else { +- s++; +- } +- continue; +- } +- } +- +- if (!(*s & 0x80)) { +- *d++ = *s++; +- } else { +- size_t siz; +- /* Get the size of the next MB character. */ +- next_codepoint(s,&siz); +- switch(siz) { +- case 5: +- *d++ = *s++; +- /*fall through*/ +- case 4: +- *d++ = *s++; +- /*fall through*/ +- case 3: +- *d++ = *s++; +- /*fall through*/ +- case 2: +- *d++ = *s++; +- /*fall through*/ +- case 1: +- *d++ = *s++; +- break; +- default: +- break; +- } +- } +- start_of_name_component = false; +- } +- *d = '\0'; +- +- /* And must not end in '/' */ +- if (d > destname + 1 && (*(d-1) == '/')) { +- *(d-1) = '\0'; +- } + + DEBUG(10,("set_conn_connectpath: service %s, connectpath = %s\n", + lp_servicename(talloc_tos(), SNUM(conn)), destname )); +-- +1.9.1 + diff -Nru samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-6.patch samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-6.patch --- samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-6.patch 1970-01-01 00:00:00.000000000 +0000 +++ samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-6.patch 2017-03-16 12:57:30.000000000 +0000 @@ -0,0 +1,358 @@ +From 847a2662396ff03449cd85b8d7ba15ef56caec3f Mon Sep 17 00:00:00 2001 +From: Jeremy Allison +Date: Fri, 20 Jan 2017 11:42:39 -0800 +Subject: [PATCH] s3: VFS: shadow_copy2: Correctly initialize timestamp and + stripped variables. + +Allow the called functions to be fixed to not touch them on error. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12531 + +Signed-off-by: Jeremy Allison +Reviewed-by: Uri Simchoni +(backported from commit 0a190f4dd950c947d47c42163d11ea4bd6e6e508) +--- + source3/modules/vfs_shadow_copy2.c | 118 +++++++++++++++++++------------------ + 1 file changed, 62 insertions(+), 56 deletions(-) + +Index: samba-4.4.5+dfsg/source3/modules/vfs_shadow_copy2.c +=================================================================== +--- samba-4.4.5+dfsg.orig/source3/modules/vfs_shadow_copy2.c 2017-03-16 08:57:28.642140480 -0400 ++++ samba-4.4.5+dfsg/source3/modules/vfs_shadow_copy2.c 2017-03-16 08:57:28.638140433 -0400 +@@ -228,10 +228,10 @@ + char **pstripped) + { + struct tm tm; +- time_t timestamp; ++ time_t timestamp = 0; + const char *p; + char *q; +- char *stripped; ++ char *stripped = NULL; + size_t rest_len, dst_len; + struct shadow_copy2_config *config; + const char *snapdir; +@@ -694,8 +694,8 @@ + const char *mask, + uint32_t attr) + { +- time_t timestamp; +- char *stripped; ++ time_t timestamp = 0; ++ char *stripped = NULL; + DIR *ret; + int saved_errno; + char *conv; +@@ -723,7 +723,8 @@ + const struct smb_filename *smb_fname_src, + const struct smb_filename *smb_fname_dst) + { +- time_t timestamp_src, timestamp_dst; ++ time_t timestamp_src = 0; ++ time_t timestamp_dst = 0; + + if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, + smb_fname_src->base_name, +@@ -749,7 +750,8 @@ + static int shadow_copy2_symlink(vfs_handle_struct *handle, + const char *oldname, const char *newname) + { +- time_t timestamp_old, timestamp_new; ++ time_t timestamp_old = 0; ++ time_t timestamp_new = 0; + + if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, oldname, + ×tamp_old, NULL)) { +@@ -769,7 +771,8 @@ + static int shadow_copy2_link(vfs_handle_struct *handle, + const char *oldname, const char *newname) + { +- time_t timestamp_old, timestamp_new; ++ time_t timestamp_old = 0; ++ time_t timestamp_new = 0; + + if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, oldname, + ×tamp_old, NULL)) { +@@ -789,8 +792,9 @@ + static int shadow_copy2_stat(vfs_handle_struct *handle, + struct smb_filename *smb_fname) + { +- time_t timestamp; +- char *stripped, *tmp; ++ time_t timestamp = 0; ++ char *stripped = NULL; ++ char *tmp; + int ret, saved_errno; + + if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, +@@ -828,8 +832,9 @@ + static int shadow_copy2_lstat(vfs_handle_struct *handle, + struct smb_filename *smb_fname) + { +- time_t timestamp; +- char *stripped, *tmp; ++ time_t timestamp = 0; ++ char *stripped = NULL; ++ char *tmp; + int ret, saved_errno; + + if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, +@@ -867,7 +872,7 @@ + static int shadow_copy2_fstat(vfs_handle_struct *handle, files_struct *fsp, + SMB_STRUCT_STAT *sbuf) + { +- time_t timestamp; ++ time_t timestamp = 0; + int ret; + + ret = SMB_VFS_NEXT_FSTAT(handle, fsp, sbuf); +@@ -889,8 +894,9 @@ + struct smb_filename *smb_fname, files_struct *fsp, + int flags, mode_t mode) + { +- time_t timestamp; +- char *stripped, *tmp; ++ time_t timestamp = 0; ++ char *stripped = NULL; ++ char *tmp; + int ret, saved_errno; + + if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, +@@ -925,8 +931,8 @@ + static int shadow_copy2_unlink(vfs_handle_struct *handle, + const struct smb_filename *smb_fname) + { +- time_t timestamp; +- char *stripped; ++ time_t timestamp = 0; ++ char *stripped = NULL; + int ret, saved_errno; + struct smb_filename *conv; + +@@ -959,8 +965,8 @@ + static int shadow_copy2_chmod(vfs_handle_struct *handle, const char *fname, + mode_t mode) + { +- time_t timestamp; +- char *stripped; ++ time_t timestamp = 0; ++ char *stripped = NULL; + int ret, saved_errno; + char *conv; + +@@ -986,8 +992,8 @@ + static int shadow_copy2_chown(vfs_handle_struct *handle, const char *fname, + uid_t uid, gid_t gid) + { +- time_t timestamp; +- char *stripped; ++ time_t timestamp = 0; ++ char *stripped = NULL; + int ret, saved_errno; + char *conv; + +@@ -1013,8 +1019,8 @@ + static int shadow_copy2_chdir(vfs_handle_struct *handle, + const char *fname) + { +- time_t timestamp; +- char *stripped; ++ time_t timestamp = 0; ++ char *stripped = NULL; + int ret, saved_errno; + char *conv; + +@@ -1041,8 +1047,8 @@ + const struct smb_filename *smb_fname, + struct smb_file_time *ft) + { +- time_t timestamp; +- char *stripped; ++ time_t timestamp = 0; ++ char *stripped = NULL; + int ret, saved_errno; + struct smb_filename *conv; + +@@ -1075,8 +1081,8 @@ + static int shadow_copy2_readlink(vfs_handle_struct *handle, + const char *fname, char *buf, size_t bufsiz) + { +- time_t timestamp; +- char *stripped; ++ time_t timestamp = 0; ++ char *stripped = NULL; + int ret, saved_errno; + char *conv; + +@@ -1102,8 +1108,8 @@ + static int shadow_copy2_mknod(vfs_handle_struct *handle, + const char *fname, mode_t mode, SMB_DEV_T dev) + { +- time_t timestamp; +- char *stripped; ++ time_t timestamp = 0; ++ char *stripped = NULL; + int ret, saved_errno; + char *conv; + +@@ -1129,7 +1135,7 @@ + static char *shadow_copy2_realpath(vfs_handle_struct *handle, + const char *fname) + { +- time_t timestamp; ++ time_t timestamp = 0; + char *stripped = NULL; + char *tmp = NULL; + char *result = NULL; +@@ -1462,8 +1468,8 @@ + TALLOC_CTX *mem_ctx, + struct security_descriptor **ppdesc) + { +- time_t timestamp; +- char *stripped; ++ time_t timestamp = 0; ++ char *stripped = NULL; + NTSTATUS status; + char *conv; + +@@ -1494,8 +1500,8 @@ + TALLOC_CTX *mem_ctx, + struct security_descriptor **ppdesc) + { +- time_t timestamp; +- char *stripped; ++ time_t timestamp = 0; ++ char *stripped = NULL; + NTSTATUS status; + char *conv; + +@@ -1521,8 +1527,8 @@ + static int shadow_copy2_mkdir(vfs_handle_struct *handle, + const char *fname, mode_t mode) + { +- time_t timestamp; +- char *stripped; ++ time_t timestamp = 0; ++ char *stripped = NULL; + int ret, saved_errno; + char *conv; + +@@ -1547,8 +1553,8 @@ + + static int shadow_copy2_rmdir(vfs_handle_struct *handle, const char *fname) + { +- time_t timestamp; +- char *stripped; ++ time_t timestamp = 0; ++ char *stripped = NULL; + int ret, saved_errno; + char *conv; + +@@ -1574,8 +1580,8 @@ + static int shadow_copy2_chflags(vfs_handle_struct *handle, const char *fname, + unsigned int flags) + { +- time_t timestamp; +- char *stripped; ++ time_t timestamp = 0; ++ char *stripped = NULL; + int ret, saved_errno; + char *conv; + +@@ -1602,8 +1608,8 @@ + const char *fname, const char *aname, + void *value, size_t size) + { +- time_t timestamp; +- char *stripped; ++ time_t timestamp = 0; ++ char *stripped = NULL; + ssize_t ret; + int saved_errno; + char *conv; +@@ -1632,8 +1638,8 @@ + const char *fname, + char *list, size_t size) + { +- time_t timestamp; +- char *stripped; ++ time_t timestamp = 0; ++ char *stripped = NULL; + ssize_t ret; + int saved_errno; + char *conv; +@@ -1660,8 +1666,8 @@ + static int shadow_copy2_removexattr(vfs_handle_struct *handle, + const char *fname, const char *aname) + { +- time_t timestamp; +- char *stripped; ++ time_t timestamp = 0; ++ char *stripped = NULL; + int ret, saved_errno; + char *conv; + +@@ -1689,8 +1695,8 @@ + const char *aname, const void *value, + size_t size, int flags) + { +- time_t timestamp; +- char *stripped; ++ time_t timestamp = 0; ++ char *stripped = NULL; + ssize_t ret; + int saved_errno; + char *conv; +@@ -1718,8 +1724,8 @@ + static int shadow_copy2_chmod_acl(vfs_handle_struct *handle, + const char *fname, mode_t mode) + { +- time_t timestamp; +- char *stripped; ++ time_t timestamp = 0; ++ char *stripped = NULL; + ssize_t ret; + int saved_errno; + char *conv; +@@ -1749,8 +1755,8 @@ + TALLOC_CTX *mem_ctx, + char **found_name) + { +- time_t timestamp; +- char *stripped; ++ time_t timestamp = 0; ++ char *stripped = NULL; + ssize_t ret; + int saved_errno; + char *conv; +@@ -1788,7 +1794,7 @@ + static const char *shadow_copy2_connectpath(struct vfs_handle_struct *handle, + const char *fname) + { +- time_t timestamp; ++ time_t timestamp = 0; + char *stripped = NULL; + char *tmp = NULL; + char *result = NULL; +@@ -1834,8 +1840,8 @@ + const char *path, uint64_t *bsize, + uint64_t *dfree, uint64_t *dsize) + { +- time_t timestamp; +- char *stripped; ++ time_t timestamp = 0; ++ char *stripped = NULL; + ssize_t ret; + int saved_errno; + char *conv; +@@ -1868,8 +1874,8 @@ + enum SMB_QUOTA_TYPE qtype, unid_t id, + SMB_DISK_QUOTA *dq) + { +- time_t timestamp; +- char *stripped; ++ time_t timestamp = 0; ++ char *stripped = NULL; + int ret; + int saved_errno; + char *conv; diff -Nru samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-7.patch samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-7.patch --- samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-7.patch 1970-01-01 00:00:00.000000000 +0000 +++ samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-7.patch 2017-03-16 12:57:37.000000000 +0000 @@ -0,0 +1,31 @@ +From 0d159a21294782aecfebd36109c8f3aec4f35fc8 Mon Sep 17 00:00:00 2001 +From: Jeremy Allison +Date: Fri, 20 Jan 2017 11:45:54 -0800 +Subject: [PATCH] s3: VFS: shadow_copy2: Ensure pathnames for parameters are + correctly relative and terminated. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12531 + +Signed-off-by: Jeremy Allison +Reviewed-by: Uri Simchoni +(backported from commit 979e39252bcc88e8aacb543b8bf322dd6f17fe7f) +--- + source3/modules/vfs_shadow_copy2.c | 5 +++++ + 1 file changed, 5 insertions(+) + +Index: samba-4.4.5+dfsg/source3/modules/vfs_shadow_copy2.c +=================================================================== +--- samba-4.4.5+dfsg.orig/source3/modules/vfs_shadow_copy2.c 2017-03-16 08:57:34.990214690 -0400 ++++ samba-4.4.5+dfsg/source3/modules/vfs_shadow_copy2.c 2017-03-16 08:57:34.990214690 -0400 +@@ -2132,6 +2132,11 @@ + } + } + ++ trim_string(config->mount_point, NULL, "/"); ++ trim_string(config->rel_connectpath, "/", "/"); ++ trim_string(config->snapdir, NULL, "/"); ++ trim_string(config->snapshot_basepath, NULL, "/"); ++ + DEBUG(10, ("shadow_copy2_connect: configuration:\n" + " share root: '%s'\n" + " mountpoint: '%s'\n" diff -Nru samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-8.patch samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-8.patch --- samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-8.patch 1970-01-01 00:00:00.000000000 +0000 +++ samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-8.patch 2017-03-16 12:57:43.000000000 +0000 @@ -0,0 +1,28 @@ +From 65c38d7f256cf5fdb44b9945aae4be9f3df14543 Mon Sep 17 00:00:00 2001 +From: Jeremy Allison +Date: Fri, 20 Jan 2017 11:48:40 -0800 +Subject: [PATCH] s3: VFS: shadow_copy2: Fix length comparison to ensure we + don't overstep a length. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12531 + +Signed-off-by: Jeremy Allison +Reviewed-by: Uri Simchoni +(backported from commit 37ef8d3f65bd1215717eb51b2e1cdb84a7bed348) +--- + source3/modules/vfs_shadow_copy2.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: samba-4.4.5+dfsg/source3/modules/vfs_shadow_copy2.c +=================================================================== +--- samba-4.4.5+dfsg.orig/source3/modules/vfs_shadow_copy2.c 2017-03-16 08:57:41.622292212 -0400 ++++ samba-4.4.5+dfsg/source3/modules/vfs_shadow_copy2.c 2017-03-16 08:57:41.618292165 -0400 +@@ -2094,7 +2094,7 @@ + } + + if (config->rel_connectpath == NULL && +- strlen(basedir) != strlen(handle->conn->connectpath)) { ++ strlen(basedir) < strlen(handle->conn->connectpath)) { + config->rel_connectpath = talloc_strdup(config, + handle->conn->connectpath + strlen(basedir)); + if (config->rel_connectpath == NULL) { diff -Nru samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-9.patch samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-9.patch --- samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-9.patch 1970-01-01 00:00:00.000000000 +0000 +++ samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12531-9.patch 2017-03-16 12:57:46.000000000 +0000 @@ -0,0 +1,32 @@ +From aa3a11a95bdcf91230dddb435b30033eb12068b3 Mon Sep 17 00:00:00 2001 +From: Jeremy Allison +Date: Fri, 20 Jan 2017 11:50:49 -0800 +Subject: [PATCH] s3: VFS: shadow_copy2: Add two new variables to the config + data. Not yet used. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12531 + +Signed-off-by: Jeremy Allison +Reviewed-by: Uri Simchoni +(backported from commit 72fe2b62e3ee7462e5be855b01943f28b26c36c1) +--- + source3/modules/vfs_shadow_copy2.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/source3/modules/vfs_shadow_copy2.c b/source3/modules/vfs_shadow_copy2.c +index e7ffcae..8356645 100644 +--- a/source3/modules/vfs_shadow_copy2.c ++++ b/source3/modules/vfs_shadow_copy2.c +@@ -48,6 +48,9 @@ struct shadow_copy2_config { + char *mount_point; + char *rel_connectpath; /* share root, relative to a snapshot root */ + char *snapshot_basepath; /* the absolute version of snapdir */ ++ char *shadow_cwd; /* Absolute $cwd path. */ ++ /* Absolute connectpath - can vary depending on $cwd. */ ++ char *shadow_connectpath; + }; + + static bool shadow_copy2_find_slashes(TALLOC_CTX *mem_ctx, const char *str, +-- +1.9.1 + diff -Nru samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12546.patch samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12546.patch --- samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12546.patch 1970-01-01 00:00:00.000000000 +0000 +++ samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12546.patch 2017-03-16 13:01:23.000000000 +0000 @@ -0,0 +1,53 @@ +From 1b6b200ee72744783c08326c597ee73017b3f531 Mon Sep 17 00:00:00 2001 +From: Jeremy Allison +Date: Wed, 1 Feb 2017 11:36:25 -0800 +Subject: [PATCH] s3: VFS: vfs_streams_xattr.c: Make streams_xattr_open() store + the same path as streams_xattr_recheck(). +MIME-Version: 1.0 +Content-Type: text/plain; charset=utf8 +Content-Transfer-Encoding: 8bit + +If the open is changing directories, fsp->fsp_name->base_name +will be the full path from the share root, whilst +smb_fname will be relative to the $cwd. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=12546 + +Signed-off-by: Jeremy Allison +Reviewed-by: Ralph Böhme + +Autobuild-User(master): Jeremy Allison +Autobuild-Date(master): Thu Feb 2 01:55:42 CET 2017 on sn-devel-144 + +(cherry picked from commit a24ba3e4083200ec9885363efc5769f43183fb6b) + +Autobuild-User(v4-4-test): Karolin Seeger +Autobuild-Date(v4-4-test): Tue Feb 7 13:05:34 CET 2017 on sn-devel-144 +--- + source3/modules/vfs_streams_xattr.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/source3/modules/vfs_streams_xattr.c b/source3/modules/vfs_streams_xattr.c +index b54809f..2f77525 100644 +--- a/source3/modules/vfs_streams_xattr.c ++++ b/source3/modules/vfs_streams_xattr.c +@@ -521,8 +521,15 @@ static int streams_xattr_open(vfs_handle_struct *handle, + + sio->xattr_name = talloc_strdup(VFS_MEMCTX_FSP_EXTENSION(handle, fsp), + xattr_name); ++ /* ++ * so->base needs to be a copy of fsp->fsp_name->base_name, ++ * making it identical to streams_xattr_recheck(). If the ++ * open is changing directories, fsp->fsp_name->base_name ++ * will be the full path from the share root, whilst ++ * smb_fname will be relative to the $cwd. ++ */ + sio->base = talloc_strdup(VFS_MEMCTX_FSP_EXTENSION(handle, fsp), +- smb_fname->base_name); ++ fsp->fsp_name->base_name); + sio->fsp_name_ptr = fsp->fsp_name; + sio->handle = handle; + sio->fsp = fsp; +-- +1.9.1 + diff -Nru samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12591.patch samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12591.patch --- samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12591.patch 1970-01-01 00:00:00.000000000 +0000 +++ samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/bug12591.patch 2017-03-16 13:01:30.000000000 +0000 @@ -0,0 +1,147 @@ +From 352661537b24abd9262c91d013049cff204b5eb2 Mon Sep 17 00:00:00 2001 +From: Ralph Boehme +Date: Fri, 17 Feb 2017 08:10:53 +0100 +Subject: [PATCH] vfs_streams_xattr: use fsp, not base_fsp + +The base_fsp's fd is always -1 as it's closed after being openend in +create_file_unixpath(). + +Additionally in streams_xattr_open force using of SMB_VFS_FSETXATTR() by +sticking the just created fd into the fsp (and removing it afterwards). + +Bug: https://bugzilla.samba.org/show_bug.cgi?id=12591 + +Signed-off-by: Ralph Boehme +Reviewed-by: Jeremy Allison + +Autobuild-User(master): Jeremy Allison +Autobuild-Date(master): Wed Feb 22 08:25:46 CET 2017 on sn-devel-144 + +(cherry picked from commit 021189e32ba507832b5e821e5cda8a2889225955) + +Autobuild-User(v4-4-test): Stefan Metzmacher +Autobuild-Date(v4-4-test): Sat Feb 25 05:08:00 CET 2017 on sn-devel-144 +--- + source3/modules/vfs_streams_xattr.c | 41 +++++++++++++++---------------------- + 1 file changed, 17 insertions(+), 24 deletions(-) + +diff --git a/source3/modules/vfs_streams_xattr.c b/source3/modules/vfs_streams_xattr.c +index 2f77525..956cf2e 100644 +--- a/source3/modules/vfs_streams_xattr.c ++++ b/source3/modules/vfs_streams_xattr.c +@@ -261,7 +261,7 @@ static int streams_xattr_fstat(vfs_handle_struct *handle, files_struct *fsp, + return -1; + } + +- sbuf->st_ex_size = get_xattr_size(handle->conn, fsp->base_fsp, ++ sbuf->st_ex_size = get_xattr_size(handle->conn, fsp, + io->base, io->xattr_name); + if (sbuf->st_ex_size == -1) { + return -1; +@@ -396,6 +396,7 @@ static int streams_xattr_open(vfs_handle_struct *handle, + char *xattr_name = NULL; + int baseflags; + int hostfd = -1; ++ int ret; + + DEBUG(10, ("streams_xattr_open called for %s with flags 0x%x\n", + smb_fname_str_dbg(smb_fname), flags)); +@@ -407,7 +408,6 @@ static int streams_xattr_open(vfs_handle_struct *handle, + /* If the default stream is requested, just open the base file. */ + if (is_ntfs_default_stream_smb_fname(smb_fname)) { + char *tmp_stream_name; +- int ret; + + tmp_stream_name = smb_fname->stream_name; + smb_fname->stream_name = NULL; +@@ -494,20 +494,13 @@ static int streams_xattr_open(vfs_handle_struct *handle, + DEBUG(10, ("creating or truncating attribute %s on file %s\n", + xattr_name, smb_fname->base_name)); + +- if (fsp->base_fsp->fh->fd != -1) { +- if (SMB_VFS_FSETXATTR( +- fsp->base_fsp, xattr_name, ++ fsp->fh->fd = hostfd; ++ ret = SMB_VFS_FSETXATTR(fsp, xattr_name, + &null, sizeof(null), +- flags & O_EXCL ? XATTR_CREATE : 0) == -1) { +- goto fail; +- } +- } else { +- if (SMB_VFS_SETXATTR( +- handle->conn, smb_fname->base_name, +- xattr_name, &null, sizeof(null), +- flags & O_EXCL ? XATTR_CREATE : 0) == -1) { +- goto fail; +- } ++ flags & O_EXCL ? XATTR_CREATE : 0); ++ fsp->fh->fd = -1; ++ if (ret != 0) { ++ goto fail; + } + } + +@@ -957,7 +950,7 @@ static ssize_t streams_xattr_pwrite(vfs_handle_struct *handle, + return -1; + } + +- status = get_ea_value(talloc_tos(), handle->conn, fsp->base_fsp, ++ status = get_ea_value(talloc_tos(), handle->conn, fsp, + sio->base, sio->xattr_name, &ea); + if (!NT_STATUS_IS_OK(status)) { + return -1; +@@ -981,13 +974,13 @@ static ssize_t streams_xattr_pwrite(vfs_handle_struct *handle, + + memcpy(ea.value.data + offset, data, n); + +- if (fsp->base_fsp->fh->fd != -1) { +- ret = SMB_VFS_FSETXATTR(fsp->base_fsp, ++ if (fsp->fh->fd != -1) { ++ ret = SMB_VFS_FSETXATTR(fsp, + sio->xattr_name, + ea.value.data, ea.value.length, 0); + } else { + ret = SMB_VFS_SETXATTR(fsp->conn, +- fsp->base_fsp->fsp_name->base_name, ++ fsp->fsp_name->base_name, + sio->xattr_name, + ea.value.data, ea.value.length, 0); + } +@@ -1021,7 +1014,7 @@ static ssize_t streams_xattr_pread(vfs_handle_struct *handle, + return -1; + } + +- status = get_ea_value(talloc_tos(), handle->conn, fsp->base_fsp, ++ status = get_ea_value(talloc_tos(), handle->conn, fsp, + sio->base, sio->xattr_name, &ea); + if (!NT_STATUS_IS_OK(status)) { + return -1; +@@ -1066,7 +1059,7 @@ static int streams_xattr_ftruncate(struct vfs_handle_struct *handle, + return -1; + } + +- status = get_ea_value(talloc_tos(), handle->conn, fsp->base_fsp, ++ status = get_ea_value(talloc_tos(), handle->conn, fsp, + sio->base, sio->xattr_name, &ea); + if (!NT_STATUS_IS_OK(status)) { + return -1; +@@ -1091,13 +1084,13 @@ static int streams_xattr_ftruncate(struct vfs_handle_struct *handle, + ea.value.length = offset + 1; + ea.value.data[offset] = 0; + +- if (fsp->base_fsp->fh->fd != -1) { +- ret = SMB_VFS_FSETXATTR(fsp->base_fsp, ++ if (fsp->fh->fd != -1) { ++ ret = SMB_VFS_FSETXATTR(fsp, + sio->xattr_name, + ea.value.data, ea.value.length, 0); + } else { + ret = SMB_VFS_SETXATTR(fsp->conn, +- fsp->base_fsp->fsp_name->base_name, ++ fsp->fsp_name->base_name, + sio->xattr_name, + ea.value.data, ea.value.length, 0); + } +-- +1.9.1 + diff -Nru samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/CVE-2017-2619-10.patch samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/CVE-2017-2619-10.patch --- samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/CVE-2017-2619-10.patch 1970-01-01 00:00:00.000000000 +0000 +++ samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/CVE-2017-2619-10.patch 2017-03-16 13:02:17.000000000 +0000 @@ -0,0 +1,267 @@ +From 6c455324714936063d77ff15997fcaf651d40a5f Mon Sep 17 00:00:00 2001 +From: Jeremy Allison +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 +--- + 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 + + diff -Nru samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/CVE-2017-2619-11.patch samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/CVE-2017-2619-11.patch --- samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/CVE-2017-2619-11.patch 1970-01-01 00:00:00.000000000 +0000 +++ samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/CVE-2017-2619-11.patch 2017-03-16 13:02:21.000000000 +0000 @@ -0,0 +1,51 @@ +From 0eb718b5cc05adbcb20ac5b9b0eee71aa2af81ac Mon Sep 17 00:00:00 2001 +From: Jeremy Allison +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 +--- + 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 + diff -Nru samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/CVE-2017-2619-12.patch samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/CVE-2017-2619-12.patch --- samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/CVE-2017-2619-12.patch 1970-01-01 00:00:00.000000000 +0000 +++ samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/CVE-2017-2619-12.patch 2017-03-20 14:47:07.000000000 +0000 @@ -0,0 +1,56 @@ +From 5203536696b3d813d6b4005958d137683972e58c Mon Sep 17 00:00:00 2001 +From: Ralph Boehme +Date: Sun, 19 Mar 2017 15:58:17 +0100 +Subject: [PATCH 1/2] CVE-2017-2619: s3/smbd: re-open directory after + dptr_CloseDir() + +dptr_CloseDir() will close and invalidate the fsp's file descriptor, we +have to reopen it. + +Bug: https://bugzilla.samba.org/show_bug.cgi?id=12496 + +Signed-off-by: Ralph Boehme +Reviewed-by: Uri Simchoni +--- + source3/smbd/smb2_query_directory.c | 17 +++++++++++++++++ + 1 file changed, 17 insertions(+) + +diff --git a/source3/smbd/smb2_query_directory.c b/source3/smbd/smb2_query_directory.c +index e18a279..2af029b 100644 +--- a/source3/smbd/smb2_query_directory.c ++++ b/source3/smbd/smb2_query_directory.c +@@ -24,6 +24,7 @@ + #include "../libcli/smb/smb_common.h" + #include "trans2.h" + #include "../lib/util/tevent_ntstatus.h" ++#include "system/filesys.h" + + static struct tevent_req *smbd_smb2_query_directory_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, +@@ -322,7 +323,23 @@ static struct tevent_req *smbd_smb2_query_directory_send(TALLOC_CTX *mem_ctx, + } + + if (in_flags & SMB2_CONTINUE_FLAG_REOPEN) { ++ int flags; ++ + dptr_CloseDir(fsp); ++ ++ /* ++ * dptr_CloseDir() will close and invalidate the fsp's file ++ * descriptor, we have to reopen it. ++ */ ++ ++ flags = O_RDONLY; ++#ifdef O_DIRECTORY ++ flags |= O_DIRECTORY; ++#endif ++ status = fd_open(conn, fsp, flags, 0); ++ if (tevent_req_nterror(req, status)) { ++ return tevent_req_post(req, ev); ++ } + } + + if (!smbreq->posix_pathnames) { +-- +2.9.3 + diff -Nru samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/CVE-2017-2619-13.patch samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/CVE-2017-2619-13.patch --- samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/CVE-2017-2619-13.patch 1970-01-01 00:00:00.000000000 +0000 +++ samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/CVE-2017-2619-13.patch 2017-03-20 14:47:32.000000000 +0000 @@ -0,0 +1,62 @@ +From 3cc5241fae9669a41fc0b538e96d901f467d0b0b Mon Sep 17 00:00:00 2001 +From: Ralph Boehme +Date: Sun, 19 Mar 2017 18:52:10 +0100 +Subject: [PATCH 2/2] CVE-2017-2619: s4/torture: add SMB2_FIND tests with + SMB2_CONTINUE_FLAG_REOPEN flag + +Bug: https://bugzilla.samba.org/show_bug.cgi?id=12496 + +Signed-off-by: Ralph Boehme +Reviewed-by: Uri Simchoni +--- + source4/torture/smb2/dir.c | 12 ++++++++++-- + 1 file changed, 10 insertions(+), 2 deletions(-) + +Index: samba-4.4.5+dfsg/source4/torture/smb2/dir.c +=================================================================== +--- samba-4.4.5+dfsg.orig/source4/torture/smb2/dir.c 2017-03-20 10:47:29.115932651 -0400 ++++ samba-4.4.5+dfsg/source4/torture/smb2/dir.c 2017-03-20 10:47:29.111932604 -0400 +@@ -674,7 +674,7 @@ + return true; + } + +-enum continue_type {CONT_SINGLE, CONT_INDEX, CONT_RESTART}; ++enum continue_type {CONT_SINGLE, CONT_INDEX, CONT_RESTART, CONT_REOPEN}; + + static NTSTATUS multiple_smb2_search(struct smb2_tree *tree, + TALLOC_CTX *tctx, +@@ -700,6 +700,9 @@ + + /* The search should start from the beginning everytime */ + f.in.continue_flags = SMB2_CONTINUE_FLAG_RESTART; ++ if (cont_type == CONT_REOPEN) { ++ f.in.continue_flags = SMB2_CONTINUE_FLAG_REOPEN; ++ } + + do { + status = smb2_find_level(tree, tree, &f, &count, &d); +@@ -803,18 +806,23 @@ + {"SMB2_FIND_BOTH_DIRECTORY_INFO", "SINGLE", SMB2_FIND_BOTH_DIRECTORY_INFO, RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO, CONT_SINGLE}, + {"SMB2_FIND_BOTH_DIRECTORY_INFO", "INDEX", SMB2_FIND_BOTH_DIRECTORY_INFO, RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO, CONT_INDEX}, + {"SMB2_FIND_BOTH_DIRECTORY_INFO", "RESTART", SMB2_FIND_BOTH_DIRECTORY_INFO, RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO, CONT_RESTART}, ++ {"SMB2_FIND_BOTH_DIRECTORY_INFO", "REOPEN", SMB2_FIND_BOTH_DIRECTORY_INFO, RAW_SEARCH_DATA_BOTH_DIRECTORY_INFO, CONT_REOPEN}, + {"SMB2_FIND_DIRECTORY_INFO", "SINGLE", SMB2_FIND_DIRECTORY_INFO, RAW_SEARCH_DATA_DIRECTORY_INFO, CONT_SINGLE}, + {"SMB2_FIND_DIRECTORY_INFO", "INDEX", SMB2_FIND_DIRECTORY_INFO, RAW_SEARCH_DATA_DIRECTORY_INFO, CONT_INDEX}, + {"SMB2_FIND_DIRECTORY_INFO", "RESTART", SMB2_FIND_DIRECTORY_INFO, RAW_SEARCH_DATA_DIRECTORY_INFO, CONT_RESTART}, ++ {"SMB2_FIND_DIRECTORY_INFO", "REOPEN", SMB2_FIND_DIRECTORY_INFO, RAW_SEARCH_DATA_DIRECTORY_INFO, CONT_REOPEN}, + {"SMB2_FIND_FULL_DIRECTORY_INFO", "SINGLE", SMB2_FIND_FULL_DIRECTORY_INFO, RAW_SEARCH_DATA_FULL_DIRECTORY_INFO, CONT_SINGLE}, + {"SMB2_FIND_FULL_DIRECTORY_INFO", "INDEX", SMB2_FIND_FULL_DIRECTORY_INFO, RAW_SEARCH_DATA_FULL_DIRECTORY_INFO, CONT_INDEX}, + {"SMB2_FIND_FULL_DIRECTORY_INFO", "RESTART", SMB2_FIND_FULL_DIRECTORY_INFO, RAW_SEARCH_DATA_FULL_DIRECTORY_INFO, CONT_RESTART}, ++ {"SMB2_FIND_FULL_DIRECTORY_INFO", "REOPEN", SMB2_FIND_FULL_DIRECTORY_INFO, RAW_SEARCH_DATA_FULL_DIRECTORY_INFO, CONT_REOPEN}, + {"SMB2_FIND_ID_FULL_DIRECTORY_INFO", "SINGLE", SMB2_FIND_ID_FULL_DIRECTORY_INFO, RAW_SEARCH_DATA_ID_FULL_DIRECTORY_INFO, CONT_SINGLE}, + {"SMB2_FIND_ID_FULL_DIRECTORY_INFO", "INDEX", SMB2_FIND_ID_FULL_DIRECTORY_INFO, RAW_SEARCH_DATA_ID_FULL_DIRECTORY_INFO, CONT_INDEX}, + {"SMB2_FIND_ID_FULL_DIRECTORY_INFO", "RESTART", SMB2_FIND_ID_FULL_DIRECTORY_INFO, RAW_SEARCH_DATA_ID_FULL_DIRECTORY_INFO, CONT_RESTART}, ++ {"SMB2_FIND_ID_FULL_DIRECTORY_INFO", "REOPEN", SMB2_FIND_ID_FULL_DIRECTORY_INFO, RAW_SEARCH_DATA_ID_FULL_DIRECTORY_INFO, CONT_REOPEN}, + {"SMB2_FIND_ID_BOTH_DIRECTORY_INFO", "SINGLE", SMB2_FIND_ID_BOTH_DIRECTORY_INFO, RAW_SEARCH_DATA_ID_BOTH_DIRECTORY_INFO, CONT_SINGLE}, + {"SMB2_FIND_ID_BOTH_DIRECTORY_INFO", "INDEX", SMB2_FIND_ID_BOTH_DIRECTORY_INFO, RAW_SEARCH_DATA_ID_BOTH_DIRECTORY_INFO, CONT_INDEX}, +- {"SMB2_FIND_ID_BOTH_DIRECTORY_INFO", "RESTART", SMB2_FIND_ID_BOTH_DIRECTORY_INFO, RAW_SEARCH_DATA_ID_BOTH_DIRECTORY_INFO, CONT_RESTART} ++ {"SMB2_FIND_ID_BOTH_DIRECTORY_INFO", "RESTART", SMB2_FIND_ID_BOTH_DIRECTORY_INFO, RAW_SEARCH_DATA_ID_BOTH_DIRECTORY_INFO, CONT_RESTART}, ++ {"SMB2_FIND_ID_BOTH_DIRECTORY_INFO", "REOPEN", SMB2_FIND_ID_BOTH_DIRECTORY_INFO, RAW_SEARCH_DATA_ID_BOTH_DIRECTORY_INFO, CONT_REOPEN}, + }; + + smb2_deltree(tree, DNAME); diff -Nru samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/CVE-2017-2619-1.patch samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/CVE-2017-2619-1.patch --- samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/CVE-2017-2619-1.patch 1970-01-01 00:00:00.000000000 +0000 +++ samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/CVE-2017-2619-1.patch 2017-03-16 13:01:37.000000000 +0000 @@ -0,0 +1,52 @@ +From c903ca6a227cd190b270c52ac3a84ad2148c9651 Mon Sep 17 00:00:00 2001 +From: Jeremy Allison +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 +--- + 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 + + diff -Nru samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/CVE-2017-2619-2.patch samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/CVE-2017-2619-2.patch --- samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/CVE-2017-2619-2.patch 1970-01-01 00:00:00.000000000 +0000 +++ samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/CVE-2017-2619-2.patch 2017-03-16 13:01:41.000000000 +0000 @@ -0,0 +1,59 @@ +From ef03034fd0b89f64983444d662ff16d8fe2f2f0b Mon Sep 17 00:00:00 2001 +From: Jeremy Allison +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 +--- + 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 + + diff -Nru samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/CVE-2017-2619-3.patch samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/CVE-2017-2619-3.patch --- samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/CVE-2017-2619-3.patch 1970-01-01 00:00:00.000000000 +0000 +++ samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/CVE-2017-2619-3.patch 2017-03-16 13:01:47.000000000 +0000 @@ -0,0 +1,115 @@ +From 0c3c22f38b0864e9894647aad1a4bc0241b9f4ae Mon Sep 17 00:00:00 2001 +From: Jeremy Allison +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 +--- + 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 + + diff -Nru samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/CVE-2017-2619-4.patch samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/CVE-2017-2619-4.patch --- samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/CVE-2017-2619-4.patch 1970-01-01 00:00:00.000000000 +0000 +++ samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/CVE-2017-2619-4.patch 2017-03-16 13:01:52.000000000 +0000 @@ -0,0 +1,70 @@ +From 39589a2b7de5768cc515bce58dd243d711e58fd3 Mon Sep 17 00:00:00 2001 +From: Jeremy Allison +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 +--- + 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 + + diff -Nru samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/CVE-2017-2619-5.patch samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/CVE-2017-2619-5.patch --- samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/CVE-2017-2619-5.patch 1970-01-01 00:00:00.000000000 +0000 +++ samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/CVE-2017-2619-5.patch 2017-03-16 13:01:56.000000000 +0000 @@ -0,0 +1,31 @@ +From 031ba3f1427d97c48e9911dc98a125661d9088ee Mon Sep 17 00:00:00 2001 +From: Jeremy Allison +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 +--- + 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 + + diff -Nru samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/CVE-2017-2619-6.patch samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/CVE-2017-2619-6.patch --- samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/CVE-2017-2619-6.patch 1970-01-01 00:00:00.000000000 +0000 +++ samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/CVE-2017-2619-6.patch 2017-03-16 13:02:01.000000000 +0000 @@ -0,0 +1,47 @@ +From 54d9bb3aa5b14e51bb1a2fe60ec20bc1cdad373f Mon Sep 17 00:00:00 2001 +From: Jeremy Allison +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 +--- + 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 + + diff -Nru samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/CVE-2017-2619-7.patch samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/CVE-2017-2619-7.patch --- samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/CVE-2017-2619-7.patch 1970-01-01 00:00:00.000000000 +0000 +++ samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/CVE-2017-2619-7.patch 2017-03-16 13:02:05.000000000 +0000 @@ -0,0 +1,45 @@ +From 1265c298699e0b3a3000e70e07d815c459ff461e Mon Sep 17 00:00:00 2001 +From: Jeremy Allison +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 +--- + 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 + + diff -Nru samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/CVE-2017-2619-8.patch samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/CVE-2017-2619-8.patch --- samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/CVE-2017-2619-8.patch 1970-01-01 00:00:00.000000000 +0000 +++ samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/CVE-2017-2619-8.patch 2017-03-16 13:02:09.000000000 +0000 @@ -0,0 +1,54 @@ +From 1c0a1c566a9a43c9c81d42e48b85109a34a486dd Mon Sep 17 00:00:00 2001 +From: Jeremy Allison +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 +--- + 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 + + diff -Nru samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/CVE-2017-2619-9.patch samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/CVE-2017-2619-9.patch --- samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/CVE-2017-2619-9.patch 1970-01-01 00:00:00.000000000 +0000 +++ samba-4.4.5+dfsg/debian/patches/CVE-2017-2619/CVE-2017-2619-9.patch 2017-03-16 13:02:13.000000000 +0000 @@ -0,0 +1,80 @@ +From a34ff44b2cbd396c678aebfc299495ddad6b91d1 Mon Sep 17 00:00:00 2001 +From: Jeremy Allison +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 +--- + 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 + + diff -Nru samba-4.4.5+dfsg/debian/patches/series samba-4.4.5+dfsg/debian/patches/series --- samba-4.4.5+dfsg/debian/patches/series 2016-12-12 13:12:03.000000000 +0000 +++ samba-4.4.5+dfsg/debian/patches/series 2017-03-20 14:47:25.000000000 +0000 @@ -25,3 +25,40 @@ CVE-2016-2123.patch CVE-2016-2125.patch CVE-2016-2126.patch +CVE-2017-2619/bug12387.patch +CVE-2017-2619/bug12499.patch +CVE-2017-2619/bug12531-1.patch +CVE-2017-2619/bug12531-2.patch +CVE-2017-2619/bug12531-3.patch +CVE-2017-2619/bug12531-4.patch +CVE-2017-2619/bug12531-5.patch +CVE-2017-2619/bug12531-6.patch +CVE-2017-2619/bug12531-7.patch +CVE-2017-2619/bug12531-8.patch +CVE-2017-2619/bug12531-9.patch +CVE-2017-2619/bug12531-10.patch +CVE-2017-2619/bug12531-11.patch +CVE-2017-2619/bug12531-12.patch +CVE-2017-2619/bug12531-13.patch +CVE-2017-2619/bug12531-14.patch +CVE-2017-2619/bug12531-15.patch +CVE-2017-2619/bug12531-16.patch +CVE-2017-2619/bug12531-17.patch +CVE-2017-2619/bug12531-18.patch +CVE-2017-2619/bug12531-19.patch +CVE-2017-2619/bug12531-20.patch +CVE-2017-2619/bug12546.patch +CVE-2017-2619/bug12591.patch +CVE-2017-2619/CVE-2017-2619-1.patch +CVE-2017-2619/CVE-2017-2619-2.patch +CVE-2017-2619/CVE-2017-2619-3.patch +CVE-2017-2619/CVE-2017-2619-4.patch +CVE-2017-2619/CVE-2017-2619-5.patch +CVE-2017-2619/CVE-2017-2619-6.patch +CVE-2017-2619/CVE-2017-2619-7.patch +CVE-2017-2619/CVE-2017-2619-8.patch +CVE-2017-2619/CVE-2017-2619-9.patch +CVE-2017-2619/CVE-2017-2619-10.patch +CVE-2017-2619/CVE-2017-2619-11.patch +CVE-2017-2619/CVE-2017-2619-12.patch +CVE-2017-2619/CVE-2017-2619-13.patch