diff --git a/1004-CVE-2023-3961.patch b/1004-CVE-2023-3961.patch new file mode 100644 index 0000000000000000000000000000000000000000..2253e0a472cd32993415d16b78f5b747a1274755 --- /dev/null +++ b/1004-CVE-2023-3961.patch @@ -0,0 +1,207 @@ +From 0068b0282860a4a7321bd8eb48934f9ca687aac6 Mon Sep 17 00:00:00 2001 +From: wangkaiqiang +Date: Tue, 9 Jan 2024 16:56:47 +0800 +Subject: [PATCH] fix CVE-2023-3961 + +--- + source3/rpc_client/local_np.c | 13 +++++ + source3/selftest/tests.py | 14 +++++ + source3/torture/proto.h | 1 + + source3/torture/test_smb2.c | 107 ++++++++++++++++++++++++++++++++++ + source3/torture/torture.c | 4 ++ + 5 files changed, 139 insertions(+) + +diff --git a/source3/rpc_client/local_np.c b/source3/rpc_client/local_np.c +index 5b1a818..e92f482 100644 +--- a/source3/rpc_client/local_np.c ++++ b/source3/rpc_client/local_np.c +@@ -509,6 +509,19 @@ struct tevent_req *local_np_connect_send( + return tevent_req_post(req, ev); + } + ++ /* ++ * Ensure we cannot process a path that exits ++ * the socket_dir. ++ */ ++ if (ISDOTDOT(lower_case_pipename) || ++ (strchr(lower_case_pipename, '/')!=NULL)) ++ { ++ DBG_DEBUG("attempt to connect to invalid pipe pathname %s\n", ++ lower_case_pipename); ++ tevent_req_error(req, ENOENT); ++ return tevent_req_post(req, ev); ++ } ++ + state->socketpath = talloc_asprintf( + state, "%s/np/%s", socket_dir, lower_case_pipename); + if (tevent_req_nomem(state->socketpath, req)) { +diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py +index c15f974..ae12be9 100755 +--- a/source3/selftest/tests.py ++++ b/source3/selftest/tests.py +@@ -288,6 +288,20 @@ plantestsuite("samba3.smbtorture_s3.plain.%s" % "SMB2-DEL-ON-CLOSE-NONWRITE-DELE + "", + "-l $LOCAL_PATH"]) + ++# BUG: https://bugzilla.samba.org/show_bug.cgi?id=15422 ++# Prevent bad pipenames. ++# ++plantestsuite("samba3.smbtorture_s3.smb2.SMB2-INVALID-PIPENAME", ++ "fileserver", ++ [os.path.join(samba3srcdir, ++ "script/tests/test_smbtorture_s3.sh"), ++ 'SMB2-INVALID-PIPENAME', ++ '//$SERVER_IP/tmp', ++ '$USERNAME', ++ '$PASSWORD', ++ smbtorture3, ++ "-mSMB2"]) ++ + # + # SMB2-DEL-ON-CLOSE-NONWRITE-DELETE-NO needs to run against a special fileserver share delete_no_unwrite + # +diff --git a/source3/torture/proto.h b/source3/torture/proto.h +index 551c4ea..bff48b5 100644 +--- a/source3/torture/proto.h ++++ b/source3/torture/proto.h +@@ -116,6 +116,7 @@ bool run_smb2_multi_channel(int dummy); + bool run_smb2_session_reauth(int dummy); + bool run_smb2_ftruncate(int dummy); + bool run_smb2_dir_fsync(int dummy); ++bool run_smb2_invalid_pipename(int dummy); + bool run_smb2_path_slash(int dummy); + bool run_smb2_sacl(int dummy); + bool run_smb2_quota1(int dummy); +diff --git a/source3/torture/test_smb2.c b/source3/torture/test_smb2.c +index c3f0141..8c5b6d9 100644 +--- a/source3/torture/test_smb2.c ++++ b/source3/torture/test_smb2.c +@@ -3608,3 +3608,110 @@ bool run_delete_on_close_nonwrite_delete_no_test(int dummy) + } + return ret; + } ++ ++bool run_smb2_invalid_pipename(int dummy) ++{ ++ struct cli_state *cli = NULL; ++ NTSTATUS status; ++ uint64_t fid_persistent = 0; ++ uint64_t fid_volatile = 0; ++ const char *unknown_pipe = "badpipe"; ++ const char *invalid_pipe = "../../../../../../../../../badpipe"; ++ ++ printf("Starting SMB2-INVALID-PIPENAME\n"); ++ ++ if (!torture_init_connection(&cli)) { ++ return false; ++ } ++ ++ status = smbXcli_negprot(cli->conn, ++ cli->timeout, ++ PROTOCOL_SMB2_02, ++ PROTOCOL_SMB3_11); ++ if (!NT_STATUS_IS_OK(status)) { ++ printf("smbXcli_negprot returned %s\n", nt_errstr(status)); ++ return false; ++ } ++ ++ status = cli_session_setup_creds(cli, torture_creds); ++ if (!NT_STATUS_IS_OK(status)) { ++ printf("cli_session_setup returned %s\n", nt_errstr(status)); ++ return false; ++ } ++ ++ status = cli_tree_connect(cli, "IPC$", "?????", NULL); ++ if (!NT_STATUS_IS_OK(status)) { ++ printf("cli_tree_connect returned %s\n", nt_errstr(status)); ++ return false; ++ } ++ ++ /* Try and connect to an unknown pipename. */ ++ status = smb2cli_create(cli->conn, ++ cli->timeout, ++ cli->smb2.session, ++ cli->smb2.tcon, ++ unknown_pipe, ++ SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */ ++ SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */ ++ SEC_STD_SYNCHRONIZE| ++ SEC_FILE_READ_DATA| ++ SEC_FILE_WRITE_DATA| ++ SEC_FILE_READ_ATTRIBUTE, /* desired_access, */ ++ FILE_ATTRIBUTE_NORMAL, /* file_attributes, */ ++ FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */ ++ FILE_CREATE, /* create_disposition, */ ++ 0, /* create_options, */ ++ NULL, /* smb2_create_blobs *blobs */ ++ &fid_persistent, ++ &fid_volatile, ++ NULL, /* struct smb_create_returns * */ ++ talloc_tos(), /* mem_ctx. */ ++ NULL, /* struct smb2_create_blobs * */ ++ NULL); /* struct symlink_reparse_struct */ ++ /* We should get NT_STATUS_OBJECT_NAME_NOT_FOUND */ ++ if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { ++ printf("%s:%d smb2cli_create on name %s returned %s\n", ++ __FILE__, ++ __LINE__, ++ unknown_pipe, ++ nt_errstr(status)); ++ return false; ++ } ++ ++ /* Try and connect to an invalid pipename containing unix separators. */ ++ status = smb2cli_create(cli->conn, ++ cli->timeout, ++ cli->smb2.session, ++ cli->smb2.tcon, ++ invalid_pipe, ++ SMB2_OPLOCK_LEVEL_NONE, /* oplock_level, */ ++ SMB2_IMPERSONATION_IMPERSONATION, /* impersonation_level, */ ++ SEC_STD_SYNCHRONIZE| ++ SEC_FILE_READ_DATA| ++ SEC_FILE_WRITE_DATA| ++ SEC_FILE_READ_ATTRIBUTE, /* desired_access, */ ++ FILE_ATTRIBUTE_NORMAL, /* file_attributes, */ ++ FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, /* share_access, */ ++ FILE_CREATE, /* create_disposition, */ ++ 0, /* create_options, */ ++ NULL, /* smb2_create_blobs *blobs */ ++ &fid_persistent, ++ &fid_volatile, ++ NULL, /* struct smb_create_returns * */ ++ talloc_tos(), /* mem_ctx. */ ++ NULL, /* struct smb2_create_blobs * */ ++ NULL); /* struct symlink_reparse_struct */ ++ /* ++ * We should still get NT_STATUS_OBJECT_NAME_NOT_FOUND ++ * (tested against Windows 2022). ++ */ ++ if (!NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) { ++ printf("%s:%d smb2cli_create on name %s returned %s\n", ++ __FILE__, ++ __LINE__, ++ invalid_pipe, ++ nt_errstr(status)); ++ return false; ++ } ++ return true; ++} +diff --git a/source3/torture/torture.c b/source3/torture/torture.c +index af28b17..922a1bb 100644 +--- a/source3/torture/torture.c ++++ b/source3/torture/torture.c +@@ -15592,6 +15592,10 @@ static struct { + .name = "readdir-timestamp", + .fn = run_readdir_timestamp, + }, ++ { ++ .name = "SMB2-INVALID-PIPENAME", ++ .fn = run_smb2_invalid_pipename, ++ }, + { + .name = NULL, + }, +-- +2.31.1 + diff --git a/samba.spec b/samba.spec index 5434fc0d9597faec2d5c8f56b414e55bcb1d2727..c2efc7b518f3beadfd9132931434f444c4cd6de6 100644 --- a/samba.spec +++ b/samba.spec @@ -136,7 +136,7 @@ %define samba_requires_eq() %(LC_ALL="C" echo '%*' | xargs -r rpm -q --qf 'Requires: %%{name} = %%{epoch}:%%{version}\\n' | sed -e 's/ (none):/ /' -e 's/ 0:/ /' | grep -v "is not") %global samba_version 4.17.5 -%global baserelease 3 +%global baserelease 4 # This should be rc1 or %%nil %global pre_release %nil @@ -236,6 +236,10 @@ Patch1000: 1000-CVE-2023-3347-smbd-pass-lp_ctx-to-smb-1-2-_srv_init_.patch Patch1001: 1001-CVE-2023-3347-smbd-remove-comment-in-smbd_smb2_reque.patch Patch1002: 1002-CVE-2023-3347-smbd-inline-smb2_srv_init_signing-code.patch Patch1003: 1003-CVE-2023-3347-smbd-fix-server-signing-mandatory.patch +#https://github.com/samba-team/samba/commit/ae476e1c28b797fe221172ed1066bf8efa476d8d +#https://github.com/samba-team/samba/commit/c39f90a12496fea74a11cbd8b34ad4074d2529db +#https://github.com/samba-team/samba/commit/5ed25efb0731de2062cd1d9e109dcf9e3eb5c356 +Patch1004: 1004-CVE-2023-3961.patch Requires(pre): /usr/sbin/groupadd @@ -4307,6 +4311,9 @@ fi %endif %changelog +* Tue Jan 09 2024 Kaiqiang Wang 4.17.5-4.0.1 +- Fix CVE-2023-3961 + * Tue Aug 1 2023 Liwei Ge - 4.17.5-3.0.1 - Fix CVE-2023-3347