The branch, v4-16-test has been updated via 5d5fa9a6c4c VERSION: Bump version up to Samba 4.16.12... via 225a003a043 VERSION: Disable GIT_SNAPSHOT for the 4.16.11 release. via 40053373794 WHATSNEW: Add release notes for Samba 4.16.11. via caf21883fa8 s3:rpc_server:netlogon: generate FAULT_INVALID_TAG for invalid netr_LogonGetCapabilities levels via 585df7e0220 s4:rpc_server:netlogon: generate FAULT_INVALID_TAG for invalid netr_LogonGetCapabilities levels via 5d48ea23dec s4:torture/rpc: let rpc.schannel also check netr_LogonGetCapabilities with different levels via 6e87858185f netlogon.idl: add support for netr_LogonGetCapabilities response level 2 via 1809843614b CVE-2023-34968: mdssvc: return a fake share path via cecd415a0ab CVE-2023-34968: mdscli: return share relative paths via d6b9c5234ff CVE-2023-34968: mdssvc: introduce an allocating wrapper to sl_pack() via 0fdfc85f28a CVE-2023-34968: mdssvc: switch to doing an early return via 34f9f1b37ec CVE-2023-34968: mdssvc: remove response blob allocation via 739f72a0703 CVE-2023-34968: rpcclient: remove response blob allocation via 7bbaa191be6 CVE-2023-34968: smbtorture: remove response blob allocation in mdssvc.c via 82cc2a422db CVE-2023-34968: mdscli: remove response blob allocation via 3636b54616e CVE-2023-34968: mdscli: use correct TALLOC memory context when allocating spotlight_blob via 8c95f7ae6b3 CVE-2023-34968: mdssvc: add missing "kMDSStoreMetaScopes" dict key in slrpc_fetch_properties() via b09e22cfc79 CVE-2023-34968: mdssvc: cache and reuse stat info in struct sl_inode_path_map via 843ec381de3 CVE-2023-34968: lib: Move subdir_of() to source3/lib/util_path.c via 5b4353cc60b CVE-2023-34967: mdssvc: add type checking to dalloc_value_for_key() via 92d014bc44b CVE-2023-34967: CI: add a test for type checking of dalloc_value_for_key() via cb6f3e22024 CVE-2023-34966: mdssvc: harden sl_unpack_loop() via 01cf3cf7a83 CVE-2023-34966: CI: test for sl_unpack_loop() via 2eabbe31f64 CVE-2022-2127: ntlm_auth: cap lanman response length value via 5c6fe5a491b CVE-2022-2127: winbindd: Fix WINBINDD_PAM_AUTH_CRAP length checks via 1dd3ae281b9 CVE-2022-2127: s3:winbind: Move big NTLMv2 blob checks to parent process from 76fc517cc54 VERSION: Bump version up to Samba 4.16.11...
https://git.samba.org/?p=samba.git;a=shortlog;h=v4-16-test - Log ----------------------------------------------------------------- commit 5d5fa9a6c4c46152785b4c3d1a42ae5172ccbf6f Author: Jule Anger <jan...@samba.org> Date: Wed Jul 19 16:50:00 2023 +0200 VERSION: Bump version up to Samba 4.16.12... and re-enable GIT_SNAPSHOT. Signed-off-by: Jule Anger <jan...@samba.org> ----------------------------------------------------------------------- Summary of changes: VERSION | 2 +- WHATSNEW.txt | 74 +++++++- librpc/idl/netlogon.idl | 1 + python/samba/tests/blackbox/mdsearch.py | 8 +- python/samba/tests/dcerpc/mdssvc.py | 26 +-- source3/lib/util_path.c | 52 ++++++ source3/lib/util_path.h | 4 + source3/rpc_client/cli_mdssvc.c | 191 ++++++++++++++++---- source3/rpc_client/cli_mdssvc_private.h | 4 + source3/rpc_client/cli_mdssvc_util.c | 148 ++++++++------- source3/rpc_client/cli_mdssvc_util.h | 4 + source3/rpc_server/mdssvc/dalloc.c | 14 +- source3/rpc_server/mdssvc/marshalling.c | 45 +++-- source3/rpc_server/mdssvc/marshalling.h | 9 +- source3/rpc_server/mdssvc/mdssvc.c | 142 ++++++++++----- source3/rpc_server/mdssvc/mdssvc.h | 7 +- source3/rpc_server/mdssvc/srv_mdssvc_nt.c | 32 ++-- source3/rpc_server/netlogon/srv_netlog_nt.c | 29 ++- source3/rpcclient/cmd_spotlight.c | 48 +---- source3/utils/ntlm_auth.c | 8 +- source3/winbindd/winbindd_pam.c | 12 -- source3/winbindd/winbindd_pam_auth_crap.c | 23 +++ source4/rpc_server/netlogon/dcerpc_netlogon.c | 28 ++- source4/torture/rpc/mdssvc.c | 250 +++++++++++++++++++++++--- source4/torture/rpc/netlogon.c | 77 +++++++- 25 files changed, 945 insertions(+), 293 deletions(-) Changeset truncated at 500 lines: diff --git a/VERSION b/VERSION index 22fca36686e..ad4024f1e17 100644 --- a/VERSION +++ b/VERSION @@ -25,7 +25,7 @@ ######################################################## SAMBA_VERSION_MAJOR=4 SAMBA_VERSION_MINOR=16 -SAMBA_VERSION_RELEASE=11 +SAMBA_VERSION_RELEASE=12 ######################################################## # If a official release has a serious bug # diff --git a/WHATSNEW.txt b/WHATSNEW.txt index 4ddfe2db83c..2b6da8e411c 100644 --- a/WHATSNEW.txt +++ b/WHATSNEW.txt @@ -1,3 +1,74 @@ + =============================== + Release Notes for Samba 4.16.11 + July 19, 2023 + =============================== + + +This is a security release in order to address the following defects: + +o CVE-2022-2127: When winbind is used for NTLM authentication, a maliciously + crafted request can trigger an out-of-bounds read in winbind + and possibly crash it. + https://www.samba.org/samba/security/CVE-2022-2127.html + +o CVE-2023-34966: An infinite loop bug in Samba's mdssvc RPC service for + Spotlight can be triggered by an unauthenticated attacker by + issuing a malformed RPC request. + https://www.samba.org/samba/security/CVE-2023-34966.html + +o CVE-2023-34967: Missing type validation in Samba's mdssvc RPC service for + Spotlight can be used by an unauthenticated attacker to + trigger a process crash in a shared RPC mdssvc worker process. + https://www.samba.org/samba/security/CVE-2023-34967.html + +o CVE-2023-34968: As part of the Spotlight protocol Samba discloses the server- + side absolute path of shares and files and directories in + search results. + https://www.samba.org/samba/security/CVE-2023-34968.html + + +Changes since 4.16.10 +--------------------- + +o Ralph Boehme <s...@samba.org> + * BUG 15072: CVE-2022-2127. + * BUG 15340: CVE-2023-34966. + * BUG 15341: CVE-2023-34967. + * BUG 15388: CVE-2023-34968. + +o Samuel Cabrero <scabr...@samba.org> + * BUG 15072: CVE-2022-2127. + +o Volker Lendecke <v...@samba.org> + * BUG 15072: CVE-2022-2127. + +o Stefan Metzmacher <me...@samba.org> + * BUG 15418: Secure channel faulty since Windows 10/11 update 07/2023. + + +####################################### +Reporting bugs & Development Discussion +####################################### + +Please discuss this release on the samba-technical mailing list or by +joining the #samba-technical:matrix.org matrix room, or +#samba-technical IRC channel on irc.libera.chat. + +If you do report problems then please try to send high quality +feedback. If you don't provide vital information to help us track down +the problem then you will probably be ignored. All bug reports should +be filed under the Samba 4.1 and newer product in the project's Bugzilla +database (https://bugzilla.samba.org/). + + +====================================================================== +== Our Code, Our Bugs, Our Responsibility. +== The Samba Team +====================================================================== + + +Release notes for older releases follow: +---------------------------------------- =============================== Release Notes for Samba 4.16.10 March 29, 2023 @@ -56,8 +127,7 @@ database (https://bugzilla.samba.org/). ====================================================================== -Release notes for older releases follow: ----------------------------------------- +---------------------------------------------------------------------- ============================== Release Notes for Samba 4.16.9 February 16, 2023 diff --git a/librpc/idl/netlogon.idl b/librpc/idl/netlogon.idl index d956a661fff..b51767136d3 100644 --- a/librpc/idl/netlogon.idl +++ b/librpc/idl/netlogon.idl @@ -1241,6 +1241,7 @@ interface netlogon /* Function 0x15 */ typedef [switch_type(uint32)] union { [case(1)] netr_NegotiateFlags server_capabilities; + [case(2)] netr_NegotiateFlags server_capabilities; } netr_Capabilities; NTSTATUS netr_LogonGetCapabilities( diff --git a/python/samba/tests/blackbox/mdsearch.py b/python/samba/tests/blackbox/mdsearch.py index c9156ae6e0e..c8e75661f15 100644 --- a/python/samba/tests/blackbox/mdsearch.py +++ b/python/samba/tests/blackbox/mdsearch.py @@ -76,10 +76,7 @@ class MdfindBlackboxTests(BlackboxTestCase): self.t.start() time.sleep(1) - pipe = mdssvc.mdssvc('ncacn_np:fileserver[/pipe/mdssvc]', self.get_loadparm()) - conn = mdscli.conn(pipe, 'spotlight', '/foo') - self.sharepath = conn.sharepath() - conn.disconnect(pipe) + self.sharepath = os.environ["LOCAL_PATH"] for file in testfiles: f = open("%s/%s" % (self.sharepath, file), "w") @@ -126,5 +123,4 @@ class MdfindBlackboxTests(BlackboxTestCase): output = self.check_output("mdsearch --configfile=%s -U %s%%%s fileserver spotlight '*==\"samba*\"'" % (config, username, password)) actual = output.decode('utf-8').splitlines() - expected = ["%s/%s" % (self.sharepath, file) for file in testfiles] - self.assertEqual(expected, actual) + self.assertEqual(testfiles, actual) diff --git a/python/samba/tests/dcerpc/mdssvc.py b/python/samba/tests/dcerpc/mdssvc.py index b0df509ddc7..5002e5d26d6 100644 --- a/python/samba/tests/dcerpc/mdssvc.py +++ b/python/samba/tests/dcerpc/mdssvc.py @@ -84,10 +84,11 @@ class MdssvcTests(RpcInterfaceTestCase): self.t = threading.Thread(target=MdssvcTests.http_server, args=(self,)) self.t.setDaemon(True) self.t.start() + self.sharepath = os.environ["LOCAL_PATH"] time.sleep(1) conn = mdscli.conn(self.pipe, 'spotlight', '/foo') - self.sharepath = conn.sharepath() + self.fakepath = conn.sharepath() conn.disconnect(self.pipe) for file in testfiles: @@ -105,12 +106,11 @@ class MdssvcTests(RpcInterfaceTestCase): self.server.serve_forever() def run_test(self, query, expect, json_in, json_out): - expect = [s.replace("%BASEPATH%", self.sharepath) for s in expect] self.server.json_in = json_in.replace("%BASEPATH%", self.sharepath) self.server.json_out = json_out.replace("%BASEPATH%", self.sharepath) self.conn = mdscli.conn(self.pipe, 'spotlight', '/foo') - search = self.conn.search(self.pipe, query, self.sharepath) + search = self.conn.search(self.pipe, query, self.fakepath) # Give it some time, the get_results() below returns immediately # what's available, so if we ask to soon, we might get back no results @@ -141,7 +141,7 @@ class MdssvcTests(RpcInterfaceTestCase): ] } }''' - exp_results = ["%BASEPATH%/foo", "%BASEPATH%/bar"] + exp_results = ["foo", "bar"] self.run_test('*=="samba*"', exp_results, exp_json_query, fake_json_response) def test_mdscli_search_escapes(self): @@ -181,14 +181,14 @@ class MdssvcTests(RpcInterfaceTestCase): } }''' exp_results = [ - r"%BASEPATH%/x+x", - r"%BASEPATH%/x*x", - r"%BASEPATH%/x=x", - r"%BASEPATH%/x'x", - r"%BASEPATH%/x?x", - r"%BASEPATH%/x x", - r"%BASEPATH%/x(x", - "%BASEPATH%/x\"x", - r"%BASEPATH%/x\x", + r"x+x", + r"x*x", + r"x=x", + r"x'x", + r"x?x", + r"x x", + r"x(x", + "x\"x", + r"x\x", ] self.run_test(sl_query, exp_results, exp_json_query, fake_json_response) diff --git a/source3/lib/util_path.c b/source3/lib/util_path.c index c34b734384c..e6bed724551 100644 --- a/source3/lib/util_path.c +++ b/source3/lib/util_path.c @@ -23,6 +23,8 @@ #include "replace.h" #include <talloc.h> +#include "lib/util/debug.h" +#include "lib/util/fault.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 3e7d04de550..0ea508bf5bb 100644 --- a/source3/lib/util_path.h +++ b/source3/lib/util_path.h @@ -31,5 +31,9 @@ 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_client/cli_mdssvc.c b/source3/rpc_client/cli_mdssvc.c index 82d14372fe4..03aed61c00c 100644 --- a/source3/rpc_client/cli_mdssvc.c +++ b/source3/rpc_client/cli_mdssvc.c @@ -43,10 +43,12 @@ char *mdscli_get_basepath(TALLOC_CTX *mem_ctx, struct mdscli_connect_state { struct tevent_context *ev; struct mdscli_ctx *mdscli_ctx; + struct mdssvc_blob response_blob; }; static void mdscli_connect_open_done(struct tevent_req *subreq); static void mdscli_connect_unknown1_done(struct tevent_req *subreq); +static void mdscli_connect_fetch_props_done(struct tevent_req *subreq); struct tevent_req *mdscli_connect_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, @@ -111,6 +113,7 @@ static void mdscli_connect_open_done(struct tevent_req *subreq) struct mdscli_connect_state *state = tevent_req_data( req, struct mdscli_connect_state); struct mdscli_ctx *mdscli_ctx = state->mdscli_ctx; + size_t share_path_len; NTSTATUS status; status = dcerpc_mdssvc_open_recv(subreq, state); @@ -120,6 +123,18 @@ static void mdscli_connect_open_done(struct tevent_req *subreq) return; } + share_path_len = strlen(mdscli_ctx->mdscmd_open.share_path); + if (share_path_len < 1 || share_path_len > UINT16_MAX) { + tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR); + return; + } + mdscli_ctx->mdscmd_open.share_path_len = share_path_len; + + if (mdscli_ctx->mdscmd_open.share_path[share_path_len-1] == '/') { + mdscli_ctx->mdscmd_open.share_path[share_path_len-1] = '\0'; + mdscli_ctx->mdscmd_open.share_path_len--; + } + subreq = dcerpc_mdssvc_unknown1_send( state, state->ev, @@ -146,6 +161,8 @@ static void mdscli_connect_unknown1_done(struct tevent_req *subreq) subreq, struct tevent_req); struct mdscli_connect_state *state = tevent_req_data( req, struct mdscli_connect_state); + struct mdscli_ctx *mdscli_ctx = state->mdscli_ctx; + struct mdssvc_blob request_blob; NTSTATUS status; status = dcerpc_mdssvc_unknown1_recv(subreq, state); @@ -154,6 +171,108 @@ static void mdscli_connect_unknown1_done(struct tevent_req *subreq) return; } + status = mdscli_blob_fetch_props(state, + state->mdscli_ctx, + &request_blob); + if (tevent_req_nterror(req, status)) { + return; + } + + subreq = dcerpc_mdssvc_cmd_send(state, + state->ev, + mdscli_ctx->bh, + &mdscli_ctx->ph, + 0, + mdscli_ctx->dev, + mdscli_ctx->mdscmd_open.unkn2, + 0, + mdscli_ctx->flags, + request_blob, + 0, + mdscli_ctx->max_fragment_size, + 1, + mdscli_ctx->max_fragment_size, + 0, + 0, + &mdscli_ctx->mdscmd_cmd.fragment, + &state->response_blob, + &mdscli_ctx->mdscmd_cmd.unkn9); + if (tevent_req_nomem(subreq, req)) { + return; + } + tevent_req_set_callback(subreq, mdscli_connect_fetch_props_done, req); + mdscli_ctx->async_pending++; + return; +} + +static void mdscli_connect_fetch_props_done(struct tevent_req *subreq) +{ + struct tevent_req *req = tevent_req_callback_data( + subreq, struct tevent_req); + struct mdscli_connect_state *state = tevent_req_data( + req, struct mdscli_connect_state); + struct mdscli_ctx *mdscli_ctx = state->mdscli_ctx; + DALLOC_CTX *d = NULL; + sl_array_t *path_scope_array = NULL; + char *path_scope = NULL; + NTSTATUS status; + bool ok; + + status = dcerpc_mdssvc_cmd_recv(subreq, state); + TALLOC_FREE(subreq); + state->mdscli_ctx->async_pending--; + if (tevent_req_nterror(req, status)) { + return; + } + + d = dalloc_new(state); + if (tevent_req_nomem(d, req)) { + return; + } + + ok = sl_unpack(d, + (char *)state->response_blob.spotlight_blob, + state->response_blob.length); + if (!ok) { + tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR); + return; + } + + path_scope_array = dalloc_value_for_key(d, + "DALLOC_CTX", 0, + "kMDSStorePathScopes", + "sl_array_t"); + if (path_scope_array == NULL) { + DBG_ERR("Missing kMDSStorePathScopes\n"); + tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR); + return; + } + + path_scope = dalloc_get(path_scope_array, "char *", 0); + if (path_scope == NULL) { + DBG_ERR("Missing path in kMDSStorePathScopes\n"); + tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR); + return; + } + + mdscli_ctx->path_scope_len = strlen(path_scope); + if (mdscli_ctx->path_scope_len < 1 || + mdscli_ctx->path_scope_len > UINT16_MAX) + { + DBG_ERR("Bad path_scope: %s\n", path_scope); + tevent_req_nterror(req, NT_STATUS_INTERNAL_ERROR); + return; + } + mdscli_ctx->path_scope = talloc_strdup(mdscli_ctx, path_scope); + if (tevent_req_nomem(mdscli_ctx->path_scope, req)) { + return; + } + + if (mdscli_ctx->path_scope[mdscli_ctx->path_scope_len-1] == '/') { + mdscli_ctx->path_scope[mdscli_ctx->path_scope_len-1] = '\0'; + mdscli_ctx->path_scope_len--; + } + tevent_req_done(req); } @@ -276,15 +395,6 @@ struct tevent_req *mdscli_search_send(TALLOC_CTX *mem_ctx, return tevent_req_post(req, ev); } - state->response_blob.spotlight_blob = talloc_array( - state, - uint8_t, - mdscli_ctx->max_fragment_size); - if (tevent_req_nomem(state->response_blob.spotlight_blob, req)) { - return tevent_req_post(req, ev); - } - state->response_blob.size = mdscli_ctx->max_fragment_size; - subreq = dcerpc_mdssvc_cmd_send(state, ev, mdscli_ctx->bh, @@ -457,15 +567,6 @@ struct tevent_req *mdscli_get_results_send( return tevent_req_post(req, ev); } - state->response_blob.spotlight_blob = talloc_array( - state, - uint8_t, - mdscli_ctx->max_fragment_size); - if (tevent_req_nomem(state->response_blob.spotlight_blob, req)) { - return tevent_req_post(req, ev); - } - state->response_blob.size = mdscli_ctx->max_fragment_size; - subreq = dcerpc_mdssvc_cmd_send(state, ev, mdscli_ctx->bh, @@ -681,15 +782,6 @@ struct tevent_req *mdscli_get_path_send(TALLOC_CTX *mem_ctx, return tevent_req_post(req, ev); } - state->response_blob.spotlight_blob = talloc_array( - state, - uint8_t, - mdscli_ctx->max_fragment_size); - if (tevent_req_nomem(state->response_blob.spotlight_blob, req)) { - return tevent_req_post(req, ev); - } - state->response_blob.size = mdscli_ctx->max_fragment_size; - subreq = dcerpc_mdssvc_cmd_send(state, ev, mdscli_ctx->bh, @@ -724,7 +816,10 @@ static void mdscli_get_path_done(struct tevent_req *subreq) struct mdscli_get_path_state *state = tevent_req_data( req, struct mdscli_get_path_state); DALLOC_CTX *d = NULL; + size_t pathlen; + size_t prefixlen; char *path = NULL; + const char *p = NULL; -- Samba Shared Repository