aboutsummaryrefslogtreecommitdiffstats
path: root/meta-networking/recipes-connectivity/samba/samba/CVE-2023-34968_0011.patch
diff options
context:
space:
mode:
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.patch295
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