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

tests: Add 2 tests for unique fileid's with top bit set (generated from itime) for files and directories.

smb2.fileid_unique.fileid_unique
smb2.fileid_unique.fileid_unique-dir

Create 100 files or directories as fast as we can
against a "normal" share, then read info on them
and ensure (a) top bit is set (generated from itime)
and (b) uniqueness across all generated objects
(checks poor timestamp resolution doesn't create
duplicate fileids).

This shows that even on ext4, this is enough to
cause duplicate fileids to be returned.

Add knownfail.d/fileid-unique

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

Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Christof Schmitt <cs@samba.org>
(back-ported picked from commit 30fea0d311)
This commit is contained in:
Jeremy Allison 2022-01-06 15:11:20 -08:00 committed by Jule Anger
parent 1d27e85826
commit 9f0353b2f4
5 changed files with 211 additions and 0 deletions

View File

@ -0,0 +1,2 @@
^samba3.smb2.fileid_unique.fileid_unique\(fileserver\)
^samba3.smb2.fileid_unique.fileid_unique-dir\(fileserver\)

View File

@ -878,6 +878,8 @@ for t in tests:
plansmbtorture4testsuite(t, "ad_dc", '//$SERVER/tmp -U$USERNAME%$PASSWORD')
elif t == "smb2.fileid":
plansmbtorture4testsuite(t, "nt4_dc", '//$SERVER_IP/vfs_fruit_xattr -U$USERNAME%$PASSWORD')
elif t == "smb2.fileid_unique":
plansmbtorture4testsuite(t, "fileserver", '//$SERVER_IP/tmp -U$USERNAME%$PASSWORD')
elif t == "rpc.wkssvc":
plansmbtorture4testsuite(t, "ad_member", '//$SERVER/tmp -U$DC_USERNAME%$DC_PASSWORD')
elif t == "rpc.srvsvc":

View File

@ -370,6 +370,7 @@ smb2_s3only = [
"smb2.durable-v2-delay",
"smb2.aio_delay",
"smb2.fileid",
"smb2.fileid_unique",
"smb2.timestamps",
]
smb2 = [x for x in smbtorture4_testsuites("smb2.") if x not in smb2_s3only]

View File

@ -2707,6 +2707,191 @@ done:
return ret;
}
static bool test_fileid_unique_object(
struct torture_context *tctx,
struct smb2_tree *tree,
unsigned int num_objs,
bool create_dirs)
{
TALLOC_CTX *mem_ctx = talloc_new(tctx);
char *fname = NULL;
struct smb2_handle testdirh;
struct smb2_handle h1;
struct smb2_create create;
unsigned int i;
uint64_t fileid_array[num_objs];
NTSTATUS status;
bool ret = true;
smb2_deltree(tree, DNAME);
status = torture_smb2_testdir(tree, DNAME, &testdirh);
torture_assert_ntstatus_ok_goto(tctx, status, ret, done,
"test_fileid_unique failed\n");
smb2_util_close(tree, testdirh);
/* Create num_obj files as rapidly as we can. */
for (i = 0; i < num_objs; i++) {
fname = talloc_asprintf(mem_ctx,
"%s\\testfile.%u",
DNAME,
i);
torture_assert_goto(tctx,
fname != NULL,
ret,
done,
"talloc failed\n");
create = (struct smb2_create) {
.in.desired_access = SEC_FILE_READ_ATTRIBUTE,
.in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
.in.file_attributes = FILE_ATTRIBUTE_NORMAL,
.in.create_disposition = NTCREATEX_DISP_CREATE,
.in.fname = fname,
};
if (create_dirs) {
create.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
create.in.create_options = FILE_DIRECTORY_FILE;
}
status = smb2_create(tree, tctx, &create);
if (!NT_STATUS_IS_OK(status)) {
torture_fail(tctx,
talloc_asprintf(tctx,
"test file %s could not be created\n",
fname));
TALLOC_FREE(fname);
ret = false;
goto done;
}
h1 = create.out.file.handle;
smb2_util_close(tree, h1);
TALLOC_FREE(fname);
}
/*
* Get the file ids.
*/
for (i = 0; i < num_objs; i++) {
union smb_fileinfo finfo;
fname = talloc_asprintf(mem_ctx,
"%s\\testfile.%u",
DNAME,
i);
torture_assert_goto(tctx,
fname != NULL,
ret,
done,
"talloc failed\n");
create = (struct smb2_create) {
.in.desired_access = SEC_FILE_READ_ATTRIBUTE,
.in.share_access = NTCREATEX_SHARE_ACCESS_MASK,
.in.file_attributes = FILE_ATTRIBUTE_NORMAL,
.in.create_disposition = NTCREATEX_DISP_OPEN,
.in.fname = fname,
};
if (create_dirs) {
create.in.file_attributes = FILE_ATTRIBUTE_DIRECTORY;
create.in.create_options = FILE_DIRECTORY_FILE;
}
status = smb2_create(tree, tctx, &create);
if (!NT_STATUS_IS_OK(status)) {
torture_fail(tctx,
talloc_asprintf(tctx,
"test file %s could not "
"be opened: %s\n",
fname,
nt_errstr(status)));
TALLOC_FREE(fname);
ret = false;
goto done;
}
h1 = create.out.file.handle;
finfo = (union smb_fileinfo) {
.generic.level = RAW_FILEINFO_SMB2_ALL_INFORMATION,
.generic.in.file.handle = h1,
};
status = smb2_getinfo_file(tree, tctx, &finfo);
if (!NT_STATUS_IS_OK(status)) {
torture_fail(tctx,
talloc_asprintf(tctx,
"failed to get fileid for "
"test file %s: %s\n",
fname,
nt_errstr(status)));
TALLOC_FREE(fname);
ret = false;
goto done;
}
smb2_util_close(tree, h1);
/*
* Samba created files on a "normal" share
* using itime should have the top bit of the fileid set.
*/
fileid_array[i] = finfo.all_info2.out.file_id;
if ((fileid_array[i] & 0x8000000000000000) == 0) {
torture_fail(tctx,
talloc_asprintf(tctx,
"test file %s fileid 0x%lx top "
"bit not set\n",
fname,
fileid_array[i]));
TALLOC_FREE(fname);
ret = false;
goto done;
}
TALLOC_FREE(fname);
}
/* All returned fileids must be unique. 100 is small so brute force. */
for (i = 0; i < num_objs - 1; i++) {
unsigned int j;
for (j = i + 1; j < num_objs; j++) {
if (fileid_array[i] == fileid_array[j]) {
torture_fail(tctx,
talloc_asprintf(tctx,
"fileid %u == fileid %u (0x%lu)\n",
i,
j,
fileid_array[i]));
ret = false;
goto done;
}
}
}
done:
smb2_util_close(tree, testdirh);
smb2_deltree(tree, DNAME);
talloc_free(mem_ctx);
return ret;
}
static bool test_fileid_unique(
struct torture_context *tctx,
struct smb2_tree *tree)
{
return test_fileid_unique_object(tctx, tree, 100, false);
}
static bool test_fileid_unique_dir(
struct torture_context *tctx,
struct smb2_tree *tree)
{
return test_fileid_unique_object(tctx, tree, 100, true);
}
/*
test opening quota fakefile handle and returned attributes
*/
@ -2823,3 +3008,23 @@ struct torture_suite *torture_smb2_fileid_init(TALLOC_CTX *ctx)
return suite;
}
/*
Testing for uniqueness of SMB2 File-IDs
*/
struct torture_suite *torture_smb2_fileid_unique_init(TALLOC_CTX *ctx)
{
struct torture_suite *suite = torture_suite_create(ctx,
"fileid_unique");
torture_suite_add_1smb2_test(suite,
"fileid_unique",
test_fileid_unique);
torture_suite_add_1smb2_test(suite,
"fileid_unique-dir",
test_fileid_unique_dir);
suite->description = talloc_strdup(suite, "SMB2-FILEID-UNIQUE tests");
return suite;
}

View File

@ -212,6 +212,7 @@ NTSTATUS torture_smb2_init(TALLOC_CTX *ctx)
torture_suite_add_1smb2_test(suite, "secleak", torture_smb2_sec_leak);
torture_suite_add_1smb2_test(suite, "session-id", run_sessidtest);
torture_suite_add_suite(suite, torture_smb2_deny_init(suite));
torture_suite_add_suite(suite, torture_smb2_fileid_unique_init(suite));
suite->description = talloc_strdup(suite, "SMB2-specific tests");