1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-23 17:34:34 +03:00

s3: torture: Add SMB1-TRUNCATED-SESSSETUP test.

Shows that we indirect through an uninitialized pointer and the client crashes
it's own smbd.

Add knownfail.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15420

Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
This commit is contained in:
Jeremy Allison 2023-08-11 10:39:36 -07:00 committed by Volker Lendecke
parent e7bf94b4e3
commit 963fd8aa9b
3 changed files with 193 additions and 0 deletions

View File

@ -0,0 +1 @@
^samba3.smbtorture_s3.smb1.SMB1-TRUNCATED-SESSSETUP.smbtorture\(fileserver_smb1\)

View File

@ -219,6 +219,17 @@ plantestsuite("samba3.smbtorture_s3.hidenewfiles_showdirs",
"", "",
"-l $LOCAL_PATH"]) "-l $LOCAL_PATH"])
plantestsuite("samba3.smbtorture_s3.smb1.SMB1-TRUNCATED-SESSSETUP",
"fileserver_smb1",
[os.path.join(samba3srcdir,
"script/tests/test_smbtorture_s3.sh"),
'SMB1-TRUNCATED-SESSSETUP',
'//$SERVER_IP/tmp',
'$USERNAME',
'$PASSWORD',
smbtorture3,
"-mNT1"])
# #
# MSDFS attribute tests. # MSDFS attribute tests.
# #

View File

@ -14645,6 +14645,182 @@ static bool run_local_canonicalize_path(int dummy)
} }
return true; return true;
} }
struct session_setup_nt1_truncated_state {
uint16_t vwv[13];
uint8_t bytes[20];
};
static void smb1_session_setup_nt1_truncated_done(struct tevent_req *subreq);
static struct tevent_req *smb1_session_setup_nt1_truncated_send(
TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct smbXcli_conn *conn)
{
uint16_t *vwv = NULL;
uint8_t *bytes = NULL;
const char *pass = "12345678";
const char *uname = "z";
struct session_setup_nt1_truncated_state *state = NULL;
struct tevent_req *req = NULL;
struct tevent_req *subreq = NULL;
req = tevent_req_create(mem_ctx,
&state,
struct session_setup_nt1_truncated_state);
if (req == NULL) {
return NULL;
}
vwv = &state->vwv[0];
bytes = &state->bytes[0];
SCVAL(vwv+0, 0, 0xff);
SCVAL(vwv+0, 1, 0);
SSVAL(vwv+1, 0, 0);
SSVAL(vwv+2, 0, 8192);
SSVAL(vwv+3, 0, 2);
SSVAL(vwv+4, 0, 1);
SIVAL(vwv+5, 0, 0);
SSVAL(vwv+7, 0, strlen(pass)); /* OEMPasswordLen */
SSVAL(vwv+8, 0, 0); /* UnicodePasswordLen */
SSVAL(vwv+9, 0, 0); /* reserved */
SSVAL(vwv+10, 0, 0); /* reserved */
SIVAL(vwv+11, 0, CAP_STATUS32);
memcpy(bytes, pass, strlen(pass));
bytes += strlen(pass);
memcpy(bytes, uname, strlen(uname)+1);
subreq = smb1cli_req_send(state, ev, conn,
SMBsesssetupX,
0, /* additional_flags */
0, /* clear_flags */
0, /* additional_flags2 */
0, /* clear_flags2 */
10000, /* timeout_msec */
getpid(),
NULL, /* tcon */
NULL, /* session */
13, /* wct */
state->vwv,
strlen(pass), /* Truncate length at password. */
state->bytes);
if (tevent_req_nomem(subreq, req)) {
return tevent_req_post(req, ev);
}
tevent_req_set_callback(subreq,
smb1_session_setup_nt1_truncated_done,
req);
return req;
}
static void smb1_session_setup_nt1_truncated_done(struct tevent_req *subreq)
{
struct tevent_req *req =
tevent_req_callback_data(subreq,
struct tevent_req);
struct session_setup_nt1_truncated_state *state =
tevent_req_data(req,
struct session_setup_nt1_truncated_state);
NTSTATUS status;
struct smb1cli_req_expected_response expected[] = {
{
.status = NT_STATUS_OK,
.wct = 3,
},
};
status = smb1cli_req_recv(subreq, state,
NULL,
NULL,
NULL,
NULL,
NULL, /* pvwv_offset */
NULL,
NULL,
NULL, /* pbytes_offset */
NULL,
expected, ARRAY_SIZE(expected));
TALLOC_FREE(subreq);
if (tevent_req_nterror(req, status)) {
return;
}
tevent_req_done(req);
}
static NTSTATUS smb1_session_setup_nt1_truncated_recv(struct tevent_req *req)
{
return tevent_req_simple_recv_ntstatus(req);
}
static bool run_smb1_truncated_sesssetup(int dummy)
{
struct tevent_context *ev;
struct tevent_req *req;
struct smbXcli_conn *conn;
struct sockaddr_storage ss;
NTSTATUS status;
int fd;
bool ok;
printf("Starting send truncated SMB1 sesssetup.\n");
ok = resolve_name(host, &ss, 0x20, true);
if (!ok) {
d_fprintf(stderr, "Could not resolve name %s\n", host);
return false;
}
status = open_socket_out(&ss, 445, 10000, &fd);
if (!NT_STATUS_IS_OK(status)) {
d_fprintf(stderr, "open_socket_out failed: %s\n",
nt_errstr(status));
return false;
}
conn = smbXcli_conn_create(talloc_tos(), fd, host, SMB_SIGNING_OFF, 0,
NULL, 0, NULL);
if (conn == NULL) {
d_fprintf(stderr, "smbXcli_conn_create failed\n");
return false;
}
status = smbXcli_negprot(conn, 0, PROTOCOL_NT1, PROTOCOL_NT1);
if (!NT_STATUS_IS_OK(status)) {
d_fprintf(stderr, "smbXcli_negprot failed!\n");
return false;
}
ev = samba_tevent_context_init(talloc_tos());
if (ev == NULL) {
d_fprintf(stderr, "samba_tevent_context_init failed\n");
return false;
}
req = smb1_session_setup_nt1_truncated_send(ev, ev, conn);
if (req == NULL) {
d_fprintf(stderr, "smb1_session_setup_nt1_truncated_send failed\n");
return false;
}
ok = tevent_req_poll_ntstatus(req, ev, &status);
if (!ok) {
d_fprintf(stderr, "tevent_req_poll failed with status %s\n",
nt_errstr(status));
return false;
}
status = smb1_session_setup_nt1_truncated_recv(req);
if (!NT_STATUS_IS_OK(status)) {
d_fprintf(stderr, "smb1_session_setup_nt1_truncated_recv returned "
"%s, expected NT_STATUS_OK\n",
nt_errstr(status));
return false;
}
TALLOC_FREE(conn);
return true;
}
static bool run_ign_bad_negprot(int dummy) static bool run_ign_bad_negprot(int dummy)
{ {
@ -14721,6 +14897,7 @@ static bool run_ign_bad_negprot(int dummy)
return true; return true;
} }
static double create_procs(bool (*fn)(int), bool *result) static double create_procs(bool (*fn)(int), bool *result)
{ {
int i, status; int i, status;
@ -15373,6 +15550,10 @@ static struct {
.name = "SMB2-DFS-FILENAME-LEADING-BACKSLASH", .name = "SMB2-DFS-FILENAME-LEADING-BACKSLASH",
.fn = run_smb2_dfs_filename_leading_backslash, .fn = run_smb2_dfs_filename_leading_backslash,
}, },
{
.name = "SMB1-TRUNCATED-SESSSETUP",
.fn = run_smb1_truncated_sesssetup,
},
{ {
.name = "SMB1-DFS-PATHS", .name = "SMB1-DFS-PATHS",
.fn = run_smb1_dfs_paths, .fn = run_smb1_dfs_paths,