diff options
Diffstat (limited to 'meta-networking/recipes-connectivity/samba/samba/CVE-2023-34968_0011.patch')
-rw-r--r-- | meta-networking/recipes-connectivity/samba/samba/CVE-2023-34968_0011.patch | 295 |
1 files changed, 295 insertions, 0 deletions
diff --git a/meta-networking/recipes-connectivity/samba/samba/CVE-2023-34968_0011.patch b/meta-networking/recipes-connectivity/samba/samba/CVE-2023-34968_0011.patch new file mode 100644 index 0000000000..d2bef187f7 --- /dev/null +++ b/meta-networking/recipes-connectivity/samba/samba/CVE-2023-34968_0011.patch @@ -0,0 +1,295 @@ +From 091b0265fe42878d676def5d4f5b4f8f3977b0e2 Mon Sep 17 00:00:00 2001 +From: Ralph Boehme <slow@samba.org> +Date: Mon, 5 Jun 2023 18:02:20 +0200 +Subject: [PATCH] CVE-2023-34968: mdssvc: return a fake share path Instead of + returning the real server-side absolute path of shares and search results, + return a fake absolute path replacing the path of the share with the share + name, iow for a share "test" with a server-side path of "/foo/bar", we + previously returned + + /foo/bar and + /foo/bar/search/result + +and now return + + /test and + /test/search/result + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=15388 + +Signed-off-by: Ralph Boehme <slow@samba.org> +Reviewed-by: Stefan Metzmacher <metze@samba.org> + +Upstream-Status: Backport [https://github.com/samba-team/samba/commit/091b0265fe42878d676def5d4f5b4f8f3977b0e2] + +CVE: CVE-2023-34968 + +Signed-off-by: Archana Polampalli <archana.polampalli@windriver.com> +--- + source3/lib/util_path.c | 52 ++++++++++++++++++++ + source3/lib/util_path.h | 5 ++ + source3/rpc_server/mdssvc/mdssvc.c | 60 +++++++++++++++++++++-- + source3/rpc_server/mdssvc/mdssvc.h | 1 + + source3/rpc_server/mdssvc/srv_mdssvc_nt.c | 17 +++++-- + 6 files changed, 128 insertions(+), 7 deletions(-) + mode change 100755 => 100644 source3/libads/ldap.c + +diff --git a/source3/lib/util_path.c b/source3/lib/util_path.c +index c34b734..5b5a51c 100644 +--- a/source3/lib/util_path.c ++++ b/source3/lib/util_path.c +@@ -21,8 +21,10 @@ + * along with this program. If not, see <http://www.gnu.org/licenses/>. + */ + ++#include "includes.h" + #include "replace.h" + #include <talloc.h> ++#include "lib/util/debug.h" + #include "lib/util/samba_util.h" + #include "lib/util_path.h" + +@@ -210,3 +212,53 @@ char *canonicalize_absolute_path(TALLOC_CTX *ctx, const char *pathname_in) + *p++ = '\0'; + return pathname; + } ++ ++/* ++ * Take two absolute paths, figure out if "subdir" is a proper ++ * subdirectory of "parent". Return the component relative to the ++ * "parent" without the potential "/". Take care of "parent" ++ * possibly ending in "/". ++ */ ++bool subdir_of(const char *parent, ++ size_t parent_len, ++ const char *subdir, ++ const char **_relative) ++{ ++ const char *relative = NULL; ++ bool matched; ++ ++ SMB_ASSERT(parent[0] == '/'); ++ SMB_ASSERT(subdir[0] == '/'); ++ ++ if (parent_len == 1) { ++ /* ++ * Everything is below "/" ++ */ ++ *_relative = subdir+1; ++ return true; ++ } ++ ++ if (parent[parent_len-1] == '/') { ++ parent_len -= 1; ++ } ++ ++ matched = (strncmp(subdir, parent, parent_len) == 0); ++ if (!matched) { ++ return false; ++ } ++ ++ relative = &subdir[parent_len]; ++ ++ if (relative[0] == '\0') { ++ *_relative = relative; /* nothing left */ ++ return true; ++ } ++ ++ if (relative[0] == '/') { ++ /* End of parent must match a '/' in subdir. */ ++ *_relative = relative+1; ++ return true; ++ } ++ ++ return false; ++} +diff --git a/source3/lib/util_path.h b/source3/lib/util_path.h +index 3e7d04d..6d2155a 100644 +--- a/source3/lib/util_path.h ++++ b/source3/lib/util_path.h +@@ -31,5 +31,10 @@ char *lock_path(TALLOC_CTX *mem_ctx, const char *name); + char *state_path(TALLOC_CTX *mem_ctx, const char *name); + char *cache_path(TALLOC_CTX *mem_ctx, const char *name); + char *canonicalize_absolute_path(TALLOC_CTX *ctx, const char *abs_path); ++bool subdir_of(const char *parent, ++ size_t parent_len, ++ const char *subdir, ++ const char **_relative); ++ + + #endif +diff --git a/source3/rpc_server/mdssvc/mdssvc.c b/source3/rpc_server/mdssvc/mdssvc.c +index 19257e8..d442d8d 100644 +--- a/source3/rpc_server/mdssvc/mdssvc.c ++++ b/source3/rpc_server/mdssvc/mdssvc.c +@@ -520,11 +520,14 @@ static bool inode_map_add(struct sl_query *slq, + bool mds_add_result(struct sl_query *slq, const char *path) + { + struct smb_filename *smb_fname = NULL; ++ char *fake_path = NULL; ++ const char *relative = NULL; + struct stat_ex sb; + uint32_t attr; + uint64_t ino64; + int result; + NTSTATUS status; ++ bool sub; + bool ok; + + /* +@@ -610,6 +613,17 @@ bool mds_add_result(struct sl_query *slq, const char *path) + } + } + ++ sub = subdir_of(slq->mds_ctx->spath, ++ slq->mds_ctx->spath_len, ++ path, ++ &relative); ++ if (!sub) { ++ DBG_ERR("[%s] is not inside [%s]\n", ++ path, slq->mds_ctx->spath); ++ slq->state = SLQ_STATE_ERROR; ++ return false; ++ } ++ + /* + * Add inode number and filemeta to result set, this is what + * we return as part of the result set of a query +@@ -622,18 +636,30 @@ bool mds_add_result(struct sl_query *slq, const char *path) + slq->state = SLQ_STATE_ERROR; + return false; + } ++ ++ fake_path = talloc_asprintf(slq, ++ "/%s/%s", ++ slq->mds_ctx->sharename, ++ relative); ++ if (fake_path == NULL) { ++ slq->state = SLQ_STATE_ERROR; ++ return false; ++ } ++ + ok = add_filemeta(slq->mds_ctx, + slq->reqinfo, + slq->query_results->fm_array, +- path, ++ fake_path, + &sb); + if (!ok) { + DBG_ERR("add_filemeta error\n"); ++ TALLOC_FREE(fake_path); + slq->state = SLQ_STATE_ERROR; + return false; + } + +- ok = inode_map_add(slq, ino64, path, &sb); ++ ok = inode_map_add(slq, ino64, fake_path, &sb); ++ TALLOC_FREE(fake_path); + if (!ok) { + DEBUG(1, ("inode_map_add error\n")); + slq->state = SLQ_STATE_ERROR; +@@ -840,6 +866,32 @@ static void slq_close_timer(struct tevent_context *ev, + } + } + ++/** ++ * Translate a fake scope from the client like /sharename/dir ++ * to the real server-side path, replacing the "/sharename" part ++ * with the absolute server-side path of the share. ++ **/ ++static bool mdssvc_real_scope(struct sl_query *slq, const char *fake_scope) ++{ ++ size_t sname_len = strlen(slq->mds_ctx->sharename); ++ size_t fake_scope_len = strlen(fake_scope); ++ ++ if (fake_scope_len < sname_len + 1) { ++ DBG_ERR("Short scope [%s] for share [%s]\n", ++ fake_scope, slq->mds_ctx->sharename); ++ return false; ++ } ++ ++ slq->path_scope = talloc_asprintf(slq, ++ "%s%s", ++ slq->mds_ctx->spath, ++ fake_scope + sname_len + 1); ++ if (slq->path_scope == NULL) { ++ return false; ++ } ++ return true; ++} ++ + /** + * Begin a search query + **/ +@@ -946,8 +998,8 @@ static bool slrpc_open_query(struct mds_ctx *mds_ctx, + goto error; + } + +- slq->path_scope = talloc_strdup(slq, scope); +- if (slq->path_scope == NULL) { ++ ok = mdssvc_real_scope(slq, scope); ++ if (!ok) { + goto error; + } + +diff --git a/source3/rpc_server/mdssvc/mdssvc.h b/source3/rpc_server/mdssvc/mdssvc.h +index b3bd8b9..8434812 100644 +--- a/source3/rpc_server/mdssvc/mdssvc.h ++++ b/source3/rpc_server/mdssvc/mdssvc.h +@@ -127,6 +127,7 @@ struct mds_ctx { + int snum; + const char *sharename; + const char *spath; ++ size_t spath_len; + struct connection_struct *conn; + struct sl_query *query_list; /* list of active queries */ + struct db_context *ino_path_map; /* dbwrap rbt for storing inode->path mappings */ +diff --git a/source3/rpc_server/mdssvc/srv_mdssvc_nt.c b/source3/rpc_server/mdssvc/srv_mdssvc_nt.c +index 59e2a97..b20bd2a 100644 +--- a/source3/rpc_server/mdssvc/srv_mdssvc_nt.c ++++ b/source3/rpc_server/mdssvc/srv_mdssvc_nt.c +@@ -121,6 +121,7 @@ void _mdssvc_open(struct pipes_struct *p, struct mdssvc_open *r) + loadparm_s3_global_substitution(); + int snum; + char *outpath = discard_const_p(char, r->out.share_path); ++ char *fake_path = NULL; + char *path; + NTSTATUS status; + +@@ -144,21 +145,31 @@ void _mdssvc_open(struct pipes_struct *p, struct mdssvc_open *r) + return; + } + ++ fake_path = talloc_asprintf(p->mem_ctx, "/%s", r->in.share_name); ++ if (fake_path == NULL) { ++ DBG_ERR("Couldn't create fake share path for %s\n", ++ r->in.share_name); ++ talloc_free(path); ++ p->fault_state = DCERPC_FAULT_CANT_PERFORM; ++ return; ++ } ++ + status = create_mdssvc_policy_handle(p->mem_ctx, p, + snum, + r->in.share_name, + path, + r->out.handle); + if (!NT_STATUS_IS_OK(status)) { +- DBG_ERR("Couldn't create policy handle for %s\n", ++ DBG_ERR("Couldn't create path for %s\n", + r->in.share_name); + talloc_free(path); ++ talloc_free(fake_path); + p->fault_state = DCERPC_FAULT_CANT_PERFORM; + return; + } + +- strlcpy(outpath, path, 1024); +- talloc_free(path); ++ strlcpy(outpath, fake_path, 1024); ++ talloc_free(fake_path); + return; + } + +-- +2.40.0 |