From 3f0c26a6f5091a81914f5c4cd7f7ff3f00b49548 Mon Sep 17 00:00:00 2001 From: xh Date: Thu, 16 Oct 2025 12:03:55 +0000 Subject: [PATCH] fix CVE-2025-10230 CVE-2025-9640 --- backport-0001-CVE-2025-10230.patch | 290 +++++++++++++++++++++++++++++ backport-0002-CVE-2025-10230.patch | 75 ++++++++ backport-CVE-2025-9640.patch | 49 +++++ samba.spec | 11 +- 4 files changed, 424 insertions(+), 1 deletion(-) create mode 100644 backport-0001-CVE-2025-10230.patch create mode 100644 backport-0002-CVE-2025-10230.patch create mode 100644 backport-CVE-2025-9640.patch diff --git a/backport-0001-CVE-2025-10230.patch b/backport-0001-CVE-2025-10230.patch new file mode 100644 index 0000000..955273b --- /dev/null +++ b/backport-0001-CVE-2025-10230.patch @@ -0,0 +1,290 @@ +From b1b1a8235f52160cf9a02ad92b346084c48095fc Mon Sep 17 00:00:00 2001 +From: Douglas Bagnall +Date: Tue, 9 Sep 2025 13:36:16 +1200 +Subject: [PATCH 1/2] CVE-2025-10230: s4/tests: check that wins hook sanitizes + names + +An smb.conf can contain a 'wins hook' parameter, which names a script +to run when a WINS name is changed. The man page says + + The second argument is the NetBIOS name. If the name is not a + legal name then the wins hook is not called. Legal names contain + only letters, digits, hyphens, underscores and periods. + +but it turns out the legality check is not performed if the WINS +server in question is the source4 nbt one. It is not expected that +people will run this server, but they can. This is bad because the +name is passed unescaped into a shell command line, allowing command +injection. + +For this test we don't care whether the WINS server is returning an +error code, just whether it is running the wins hook. The tests show +it often runs the hook it shouldn't, though some characters are +incidentally blocked because the name has to fit in a DN before it +gets to the hook, and DNs have a few syntactic restrictions (e.g., +blocking '<', '>', and ';'). + +The source3 WINS server that is used by Samba when not run as a DC is +not affected and not here tested. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=15903 + +Signed-off-by: Douglas Bagnall +Reviewed-by: Gary Lockyer + +Conflict: selftest/target/Samba4.pm context adapt +Reference: http://attachments.samba.org/attachment.cgi?id=18744 +--- + python/samba/tests/usage.py | 2 + + .../samba4.nbt.wins.wins_bad_names | 1 + + selftest/target/Samba4.pm | 1 + + source4/torture/nbt/wins.c | 136 +++++++++++++++++- + testprogs/blackbox/wins_hook_test | 15 ++ + 5 files changed, 152 insertions(+), 3 deletions(-) + create mode 100644 selftest/knownfail.d/samba4.nbt.wins.wins_bad_names + create mode 100755 testprogs/blackbox/wins_hook_test + +diff --git a/python/samba/tests/usage.py b/python/samba/tests/usage.py +index 3312bfe3746..afee5a5ebcd 100644 +--- a/python/samba/tests/usage.py ++++ b/python/samba/tests/usage.py +@@ -73,6 +73,7 @@ EXCLUDE_USAGE = { + 'lib/ldb/tests/python/api.py', + 'source4/selftest/tests.py', + 'buildtools/bin/waf', ++ 'testprogs/blackbox/wins_hook_test', + 'selftest/tap2subunit', + 'script/show_test_time', + 'source4/scripting/bin/subunitrun', +@@ -89,6 +90,7 @@ EXCLUDE_HELP = { + 'selftest/tap2subunit', + 'wintest/test-s3.py', + 'wintest/test-s4-howto.py', ++ 'testprogs/blackbox/wins_hook_test', + } + + +diff --git a/selftest/knownfail.d/samba4.nbt.wins.wins_bad_names b/selftest/knownfail.d/samba4.nbt.wins.wins_bad_names +new file mode 100644 +index 00000000000..52388ce5749 +--- /dev/null ++++ b/selftest/knownfail.d/samba4.nbt.wins.wins_bad_names +@@ -0,0 +1 @@ ++samba4.nbt.wins.wins_bad_names +diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm +index e917f65fc36..110f4c5072b 100755 +--- a/selftest/target/Samba4.pm ++++ b/selftest/target/Samba4.pm +@@ -1628,6 +1628,7 @@ sub provision_ad_dc_ntvfs($$$) + allow nt4 crypto = yes + raw NTLMv2 auth = yes + lsa over netlogon = yes ++ wins hook = $ENV{SRCDIR_ABS}/testprogs/blackbox/wins_hook_test + rpc server port = 1027 + auth event notification = true + dsdb event notification = true +diff --git a/source4/torture/nbt/wins.c b/source4/torture/nbt/wins.c +index 8c847b5ac50..7d7321752d6 100644 +--- a/source4/torture/nbt/wins.c ++++ b/source4/torture/nbt/wins.c +@@ -31,6 +31,10 @@ + #include "torture/nbt/proto.h" + #include "param/param.h" + ++/* rcode used when you don't want to check the rcode */ ++#define WINS_TEST_RCODE_WE_DONT_CARE 255 ++ ++ + #define CHECK_VALUE(tctx, v, correct) \ + torture_assert_int_equal(tctx, v, correct, "Incorrect value") + +@@ -137,7 +141,9 @@ static bool nbt_test_wins_name(struct torture_context *tctx, const char *address + address)); + + CHECK_STRING(tctx, io.out.wins_server, address); +- CHECK_VALUE(tctx, io.out.rcode, 0); ++ if (register_rcode != WINS_TEST_RCODE_WE_DONT_CARE) { ++ CHECK_VALUE(tctx, io.out.rcode, 0); ++ } + + torture_comment(tctx, "register the name correct address\n"); + name_register.in.name = *name; +@@ -185,7 +191,9 @@ static bool nbt_test_wins_name(struct torture_context *tctx, const char *address + talloc_asprintf(tctx, "Bad response from %s for name register\n", + address)); + +- CHECK_VALUE(tctx, name_register.out.rcode, 0); ++ if (register_rcode != WINS_TEST_RCODE_WE_DONT_CARE) { ++ CHECK_VALUE(tctx, name_register.out.rcode, 0); ++ } + CHECK_STRING(tctx, name_register.out.reply_addr, myaddress); + } + +@@ -203,7 +211,9 @@ static bool nbt_test_wins_name(struct torture_context *tctx, const char *address + torture_assert_ntstatus_ok(tctx, status, talloc_asprintf(tctx, "Bad response from %s for name register", address)); + + CHECK_STRING(tctx, io.out.wins_server, address); +- CHECK_VALUE(tctx, io.out.rcode, register_rcode); ++ if (register_rcode != WINS_TEST_RCODE_WE_DONT_CARE) { ++ CHECK_VALUE(tctx, io.out.rcode, register_rcode); ++ } + + if (register_rcode != NBT_RCODE_OK) { + return true; +@@ -532,6 +542,124 @@ static bool nbt_test_wins(struct torture_context *tctx) + return ret; + } + ++/* ++ * Test that the WINS server does not call 'wins hook' when the name ++ * contains dodgy characters. ++ */ ++static bool nbt_test_wins_bad_names(struct torture_context *tctx) ++{ ++ const char *address = NULL; ++ const char *wins_hook_file = NULL; ++ bool ret = true; ++ int err; ++ bool ok; ++ struct nbt_name name = {}; ++ size_t i, j; ++ FILE *fh = NULL; ++ ++ struct { ++ const char *name; ++ bool should_succeed; ++ } test_cases[] = { ++ {"NORMAL", true}, ++ {"|look|", false}, ++ {"look&true", false}, ++ {"look\\;false", false}, ++ {"&ls>foo", false}, /* already fails due to DN syntax */ ++ {"has spaces", false}, ++ {"hyphen-dot.0", true}, ++ }; ++ ++ wins_hook_file = talloc_asprintf(tctx, "%s/wins_hook_writes_here", ++ getenv("SELFTEST_TMPDIR")); ++ ++ if (!torture_nbt_get_name(tctx, &name, &address)) { ++ return false; ++ } ++ ++ for (i = 0; i < ARRAY_SIZE(test_cases); i++) { ++ err = unlink(wins_hook_file); ++ if (err != 0 && errno != ENOENT) { ++ /* we expect ENOENT, but nothing else */ ++ torture_comment(tctx, ++ "unlink %zu of '%s' failed\n", ++ i, wins_hook_file); ++ } ++ ++ name.name = test_cases[i].name; ++ name.type = NBT_NAME_CLIENT; ++ ok = nbt_test_wins_name(tctx, address, ++ &name, ++ NBT_NODE_H, ++ true, ++ WINS_TEST_RCODE_WE_DONT_CARE ++ ); ++ if (ok == false) { ++ /* ++ * This happens when the name interferes with ++ * the DN syntax when it is put in winsdb. ++ * ++ * The wins hook will not be reached. ++ */ ++ torture_comment(tctx, "tests for '%s' failed\n", ++ name.name); ++ } ++ ++ /* ++ * poll for the file being created by the wins hook. ++ */ ++ for (j = 0; j < 10; j++) { ++ usleep(200000); ++ fh = fopen(wins_hook_file, "r"); ++ if (fh != NULL) { ++ break; ++ } ++ } ++ ++ if (fh == NULL) { ++ if (errno == ENOENT) { ++ if (test_cases[i].should_succeed) { ++ torture_comment( ++ tctx, ++ "wins hook for '%s' failed\n", ++ test_cases[i].name); ++ ret = false; ++ } ++ } else { ++ torture_comment( ++ tctx, ++ "wins hook for '%s' unexpectedly failed with %d\n", ++ test_cases[i].name, ++ errno); ++ ret = false; ++ } ++ } else { ++ char readback[17] = {0}; ++ size_t n = fread(readback, 1, 16, fh); ++ torture_comment(tctx, ++ "wins hook wrote '%s' read '%.*s'\n", ++ test_cases[i].name, ++ (int)n, readback); ++ ++ if (! test_cases[i].should_succeed) { ++ torture_comment(tctx, ++ "wins hook for '%s' should fail\n", ++ test_cases[i].name); ++ ret = false; ++ } ++ fclose(fh); ++ } ++ } ++ err = unlink(wins_hook_file); ++ if (err != 0 && errno != ENOENT) { ++ torture_comment(tctx, "final unlink of '%s' failed\n", ++ wins_hook_file); ++ } ++ torture_assert(tctx, ret, "wins hook failure\n"); ++ return ret; ++} ++ ++ + /* + test WINS operations + */ +@@ -540,6 +668,8 @@ struct torture_suite *torture_nbt_wins(TALLOC_CTX *mem_ctx) + struct torture_suite *suite = torture_suite_create(mem_ctx, "wins"); + + torture_suite_add_simple_test(suite, "wins", nbt_test_wins); ++ torture_suite_add_simple_test(suite, "wins_bad_names", ++ nbt_test_wins_bad_names); + + return suite; + } +diff --git a/testprogs/blackbox/wins_hook_test b/testprogs/blackbox/wins_hook_test +new file mode 100755 +index 00000000000..f15379c28ca +--- /dev/null ++++ b/testprogs/blackbox/wins_hook_test +@@ -0,0 +1,15 @@ ++#!/usr/bin/python3 ++ ++import os ++import sys ++ ++filename = f"{os.environ['SELFTEST_TMPDIR']}/wins_hook_writes_here" ++ ++f = open(filename, 'wb') ++ ++# Some names may truncate argv (e.g. '&'), for which we leave the file ++# empty. ++if len(sys.argv) > 2: ++ f.write(os.fsencode(sys.argv[2])) ++ ++f.close() +-- +2.43.0 diff --git a/backport-0002-CVE-2025-10230.patch b/backport-0002-CVE-2025-10230.patch new file mode 100644 index 0000000..ce96c59 --- /dev/null +++ b/backport-0002-CVE-2025-10230.patch @@ -0,0 +1,75 @@ +From cec06776e4db805e9a8d1f2428f88895f3bf79a0 Mon Sep 17 00:00:00 2001 +From: Douglas Bagnall +Date: Wed, 3 Sep 2025 14:20:24 +1200 +Subject: [PATCH 2/2] CVE-2025-10230: s4:wins: restrict names fed to shell + +If the "wins hook" smb.conf parameter is set, the WINS server will +attempt to execute that value in a shell command line when a client +asks to modify a name. The WINS system is a trusting one, and clients +can claim any NETBIOS name they wish. + +With the source3 nmbd WINS server (since the 1999 commit now called +3db52feb1f3b2c07ce0b06ad4a7099fa6efe3fc7) the wins hook will not be +run for names that contain shell metacharacters. This restriction has +not been present on the source4 nbt WINS server, which is the WINS +server that will be used in the event that an Active Directory Domain +Controller is also running WINS. + +This allowed an unauthenticated client to execute arbitrary commands +on the server. + +This commit brings the nmbd check into the nbt WINS server, so that +the wins hook will only be run for names that contain only letters, +digits, hyphens, underscores and periods. This matches the behaviour +described in the smb.conf man page. + +The source3 nmbd WINS server has another layer of protection, in that +it uses the smb_run() exec wrapper that tries to escape arguments. We +don't do that here. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=15903 + +Signed-off-by: Douglas Bagnall +Reviewed-by: Gary Lockyer + +Conflict: NA +Reference: http://attachments.samba.org/attachment.cgi?id=18744 +--- + selftest/knownfail.d/samba4.nbt.wins.wins_bad_names | 1 - + source4/nbt_server/wins/wins_hook.c | 9 +++++++++ + 2 files changed, 9 insertions(+), 1 deletion(-) + delete mode 100644 selftest/knownfail.d/samba4.nbt.wins.wins_bad_names + +diff --git a/selftest/knownfail.d/samba4.nbt.wins.wins_bad_names b/selftest/knownfail.d/samba4.nbt.wins.wins_bad_names +deleted file mode 100644 +index 52388ce5749..00000000000 +--- a/selftest/knownfail.d/samba4.nbt.wins.wins_bad_names ++++ /dev/null +@@ -1 +0,0 @@ +-samba4.nbt.wins.wins_bad_names +diff --git a/source4/nbt_server/wins/wins_hook.c b/source4/nbt_server/wins/wins_hook.c +index 1af471b15bc..442141fecdd 100644 +--- a/source4/nbt_server/wins/wins_hook.c ++++ b/source4/nbt_server/wins/wins_hook.c +@@ -43,9 +43,18 @@ void wins_hook(struct winsdb_handle *h, const struct winsdb_record *rec, + int child; + char *cmd = NULL; + TALLOC_CTX *tmp_mem = NULL; ++ const char *p = NULL; + + if (!wins_hook_script || !wins_hook_script[0]) return; + ++ for (p = rec->name->name; *p; p++) { ++ if (!(isalnum((int)*p) || strchr_m("._-", *p))) { ++ DBG_ERR("not calling wins hook for invalid name %s\n", ++ rec->name->name); ++ return; ++ } ++ } ++ + tmp_mem = talloc_new(h); + if (!tmp_mem) goto failed; + +-- +2.43.0 + diff --git a/backport-CVE-2025-9640.patch b/backport-CVE-2025-9640.patch new file mode 100644 index 0000000..d2f5a86 --- /dev/null +++ b/backport-CVE-2025-9640.patch @@ -0,0 +1,49 @@ +From 9e1d16698bd2a395a8be3f48811391119db6152d Mon Sep 17 00:00:00 2001 +From: Andrew Walker +Date: Thu, 28 Aug 2025 19:36:19 +0000 +Subject: CVE-2025-9640: s3/modules/vfs_streams_xattr fix + unitialized write + +This commit fixes a situation in which vfs_streams_xattr could +write unitialized memory into alternate data streams if the +user writes to an offset that is beyond the current end of file +to insert a hole in it. + +BUG: https://bugzilla.samba.org/show_bug.cgi?id=15885 + +Signed-off-by: Andrew Walker +Reviewed-by: Volker Lendecke + +Conflict: NA +Reference: http://attachments.samba.org/attachment.cgi?id=18747 +--- + source3/modules/vfs_streams_xattr.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/source3/modules/vfs_streams_xattr.c b/source3/modules/vfs_streams_xattr.c +index 03ff6147cb0..4fb4f42baa0 100644 +--- a/source3/modules/vfs_streams_xattr.c ++++ b/source3/modules/vfs_streams_xattr.c +@@ -959,15 +959,18 @@ static ssize_t streams_xattr_pwrite(vfs_handle_struct *handle, + + if ((offset + n) > ea.value.length-1) { + uint8_t *tmp; ++ size_t new_sz = offset + n + 1; + + tmp = talloc_realloc(talloc_tos(), ea.value.data, uint8_t, +- offset + n + 1); ++ new_sz); + + if (tmp == NULL) { + TALLOC_FREE(ea.value.data); + errno = ENOMEM; + return -1; + } ++ ++ memset(tmp + ea.value.length, 0, new_sz - ea.value.length); + ea.value.data = tmp; + ea.value.length = offset + n + 1; + ea.value.data[offset+n] = 0; +-- +2.43.0 + diff --git a/samba.spec b/samba.spec index e75092c..f9f407a 100644 --- a/samba.spec +++ b/samba.spec @@ -50,7 +50,7 @@ Name: samba Version: 4.11.12 -Release: 36 +Release: 37 Summary: A suite for Linux to interoperate with Windows License: GPLv3+ and LGPLv3+ @@ -358,6 +358,9 @@ Patch6427: backport-0006-CVE-2018-14628.patch Patch6428: remove-sensitive-info.patch Patch6429: backport-wb_sids2xids-build-state-idmap_doms-based-on-wb_parent_idmap_config.patch Patch6430: backport-wb_sids2xids-maintain-struct-wbint_TransIDArray-all_ids-as-cache.patch +Patch6431: backport-0001-CVE-2025-10230.patch +Patch6432: backport-0002-CVE-2025-10230.patch +Patch6433: backport-CVE-2025-9640.patch BuildRequires: avahi-devel cups-devel dbus-devel docbook-style-xsl e2fsprogs-devel gawk gnupg2 gnutls-devel >= 3.4.7 gpgme-devel @@ -3416,6 +3419,12 @@ fi %{_mandir}/man* %changelog +* Thu Oct 16 2025 xinghe - 4.11.12-37 +- Type:cves +- CVE:CVE-2025-10230 CVE-2025-9640 +- SUG:NA +- DESC:fix CVE-2025-10230 CVE-2025-9640 + * Fri Mar 14 2025 wangxiaomeng - 4.11.12-36 - Type:bugfix - ID:NA -- Gitee