FSCTL_READ_FILE_USN_DATA on "SmartScreen" alternate data stream

Andrew Walker awalker at ixsystems.com
Thu Nov 10 21:03:28 UTC 2022


> Can you give the entire call stack. Might be easier to just change the
upper level code to pass on metadata_fsp(fsp) instead.

Yeah, that's not a problem. I'll also attach my WIP torture test at bottom
of this email to save you perhaps a little effort. Let me know if
formatting gets blown up and I'll email git diff. Torture test against
windows server succeeds BTW (STATUS_OK).

Here's linux core:
```
(gdb) bt
#0  __GI_raise (sig=sig at entry=6) at ../sysdeps/unix/sysv/linux/raise.c:50
#1  0x00007f68dcd94537 in __GI_abort () at abort.c:79
#2  0x00007f68dd281960 in dump_core () at ../../source3/lib/dumpcore.c:338
#3  0x00007f68dd28ef01 in smb_panic_s3 (why=<optimized out>) at
../../source3/lib/util.c:713
#4  0x00007f68dcfa78ea in smb_panic (why=why at entry=0x7f68dd4b78c0 "assert
failed: !fsp_is_alternate_stream(fsp)") at ../../lib/util/fault.c:198
#5  0x00007f68dd3c173e in vfswrap_fsctl (handle=0x558c37ccb510,
fsp=0x558c37d33c60, ctx=0x558c37d2eb40, function=590016,
req_flags=<optimized out>, _in_data=0x0, in_len=0,
_out_data=0x7fff0dc5aab0,
    max_out_len=64, out_len=0x7fff0dc5aaa0) at
../../source3/modules/vfs_default.c:1497
#6  0x00007f68dd439789 in smb2_ioctl_filesys (ctl_code=ctl_code at entry=590016,
ev=ev at entry=0x558c37cb3340, req=req at entry=0x558c37d2e980,
state=0x558c37d2eb40)
    at ../../source3/smbd/smb2_ioctl_filesys.c:788
#7  0x00007f68dd4388c3 in smbd_smb2_ioctl_send (in_flags=1,
in_max_output=<optimized out>, in_input=..., in_ctl_code=<optimized out>,
fsp=0x558c37d33c60, smb2req=0x558c37cb0400, ev=0x558c37cb3340,
    mem_ctx=0x558c37cb0400) at ../../source3/smbd/smb2_ioctl.c:465
#8  smbd_smb2_request_process_ioctl (req=req at entry=0x558c37cb0400) at
../../source3/smbd/smb2_ioctl.c:224
#9  0x00007f68dd428172 in smbd_smb2_request_dispatch
(req=req at entry=0x558c37cb0400)
at ../../source3/smbd/smb2_server.c:3435
#10 0x00007f68dd429227 in smbd_smb2_io_handler (fde_flags=<optimized out>,
xconn=0x558c37cdd8e0) at ../../source3/smbd/smb2_server.c:5008
#11 smbd_smb2_connection_handler (ev=<optimized out>, fde=<optimized out>,
flags=<optimized out>, private_data=<optimized out>) at
../../source3/smbd/smb2_server.c:5046
#12 0x00007f68dd1c24f1 in tevent_common_invoke_fd_handler
(fde=fde at entry=0x558c37cdc820,
flags=1, removed=removed at entry=0x0) at ../../lib/tevent/tevent_fd.c:142
#13 0x00007f68dd1c8ae7 in epoll_event_loop (tvalp=0x7fff0dc5ad80,
epoll_ev=0x558c37cdbf70) at ../../lib/tevent/tevent_epoll.c:737
#14 epoll_event_loop_once (ev=<optimized out>, location=<optimized out>) at
../../lib/tevent/tevent_epoll.c:938
#15 0x00007f68dd1c6c27 in std_event_loop_once (ev=0x558c37cb3340,
location=0x7f68dd4d9d10 "../../source3/smbd/smb2_process.c:2015") at
../../lib/tevent/tevent_standard.c:114
#16 0x00007f68dd1c18a4 in _tevent_loop_once (ev=ev at entry=0x558c37cb3340,
location=location at entry=0x7f68dd4d9d10
"../../source3/smbd/smb2_process.c:2015") at ../../lib/tevent/tevent.c:828
#17 0x00007f68dd1c1b8b in tevent_common_loop_wait (ev=0x558c37cb3340,
location=0x7f68dd4d9d10 "../../source3/smbd/smb2_process.c:2015") at
../../lib/tevent/tevent.c:951
#18 0x00007f68dd1c6bc7 in std_event_loop_wait (ev=0x558c37cb3340,
location=0x7f68dd4d9d10 "../../source3/smbd/smb2_process.c:2015") at
../../lib/tevent/tevent_standard.c:145
#19 0x00007f68dd416380 in smbd_process (ev_ctx=ev_ctx at entry=0x558c37cb3340,
msg_ctx=msg_ctx at entry=0x558c37ccf9b0, sock_fd=sock_fd at entry=34,
interactive=interactive at entry=false)
    at ../../source3/smbd/smb2_process.c:2015
#20 0x0000558c365f0061 in smbd_accept_connection (ev=0x558c37cb3340,
fde=<optimized out>, flags=<optimized out>, private_data=<optimized out>)
at ../../source3/smbd/server.c:1037
#21 0x00007f68dd1c24f1 in tevent_common_invoke_fd_handler
(fde=fde at entry=0x558c37cc2600,
flags=1, removed=removed at entry=0x0) at ../../lib/tevent/tevent_fd.c:142
#22 0x00007f68dd1c8ae7 in epoll_event_loop (tvalp=0x7fff0dc5b010,
epoll_ev=0x558c37cd04a0) at ../../lib/tevent/tevent_epoll.c:737
#23 epoll_event_loop_once (ev=<optimized out>, location=<optimized out>) at
../../lib/tevent/tevent_epoll.c:938
#24 0x00007f68dd1c6c27 in std_event_loop_once (ev=0x558c37cb3340,
location=0x558c365f2eb0 "../../source3/smbd/server.c:1381") at
../../lib/tevent/tevent_standard.c:114
#25 0x00007f68dd1c18a4 in _tevent_loop_once (ev=ev at entry=0x558c37cb3340,
location=location at entry=0x558c365f2eb0 "../../source3/smbd/server.c:1381")
at ../../lib/tevent/tevent.c:828
#26 0x00007f68dd1c1b8b in tevent_common_loop_wait (ev=0x558c37cb3340,
location=0x558c365f2eb0 "../../source3/smbd/server.c:1381") at
../../lib/tevent/tevent.c:951
#27 0x00007f68dd1c6bc7 in std_event_loop_wait (ev=0x558c37cb3340,
location=0x558c365f2eb0 "../../source3/smbd/server.c:1381") at
../../lib/tevent/tevent_standard.c:145
#28 0x0000558c365ed219 in smbd_parent_loop (parent=0x558c37cacde0,
ev_ctx=0x558c37cb3340) at ../../source3/smbd/server.c:1381
#29 main (argc=<optimized out>, argv=<optimized out>) at
../../source3/smbd/server.c:2125
```

Torture test:
```
static NTSTATUS test_ioctl_stream(struct torture_context *torture,
      TALLOC_CTX *mem_ctx,
      struct smb2_tree *tree,
      struct smb2_handle fh)
{
union smb_ioctl ioctl;
NTSTATUS status;
struct file_zero_data_info zdata_info;
TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
if (tmp_ctx == NULL) {
return NT_STATUS_NO_MEMORY;
}

ZERO_STRUCT(ioctl);
ioctl.smb2.level = RAW_IOCTL_SMB2;
ioctl.smb2.in.file.handle = fh;
ioctl.smb2.in.function = FSCTL_CREATE_OR_GET_OBJECT_ID,
ioctl.smb2.in.max_output_response = 64;
ioctl.smb2.in.flags = SMB2_IOCTL_FLAG_IS_FSCTL;

status = smb2_ioctl(tree, tmp_ctx, &ioctl.smb2);
if (!NT_STATUS_IS_OK(status)) {
goto err_out;
}

status = NT_STATUS_OK;
err_out:
talloc_free(tmp_ctx);
return status;
}

bool test_ioctl_alternate_data_stream(struct torture_context *tctx)
{
bool ret = true;
int offset, beyond_final_zero;
const char *fname = DNAME "\\test_stream_ioctl_dir";
const char *sname = DNAME "\\test_stream_ioctl_dir:stream";
NTSTATUS status;
struct smb2_create create = { };
struct smb2_tree *tree = NULL;
struct smb2_handle h1 = {{0}};
const char *data = "test data";

if (!torture_smb2_connection(tctx, &tree)) {
torture_comment(tctx, "Initializing smb2 connection failed.\n");
return false;
}

smb2_deltree(tree, DNAME);

status = torture_smb2_testdir(tree, DNAME, &h1);
torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
"torture_smb2_testdir failed\n");

smb2_util_close(tree, h1);
create = (struct smb2_create) {
.in.desired_access = SEC_FILE_ALL,
.in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
.in.file_attributes = FILE_ATTRIBUTE_HIDDEN,
.in.create_disposition = NTCREATEX_DISP_CREATE,
.in.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION,
.in.fname = fname,
};

status = smb2_create(tree, tctx, &create);
torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
"smb2_create failed\n");

h1 = create.out.file.handle;
status = smb2_util_close(tree, h1);

create = (struct smb2_create) {
.in.desired_access = SEC_FILE_ALL,
.in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
.in.file_attributes = FILE_ATTRIBUTE_NORMAL,
.in.create_disposition = NTCREATEX_DISP_CREATE,
.in.impersonation_level = SMB2_IMPERSONATION_IMPERSONATION,
.in.fname = sname,
};
status = smb2_create(tree, tctx, &create);
torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
"smb2_create failed\n");
        h1 = create.out.file.handle;

status = test_ioctl_stream(tctx, tctx, tree, h1);
if (!NT_STATUS_IS_OK(status)) {
smb2_util_close(tree, h1);
torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
"test_ioctl_stream failed\n");
}
done:
return ret;
}
```


More information about the samba-technical mailing list