]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s3: torture: Add POSIX-SYMLINK-SETPATHINFO regression test.
authorJeremy Allison <jra@samba.org>
Tue, 15 Jun 2021 22:11:20 +0000 (15:11 -0700)
committerNoel Power <npower@samba.org>
Wed, 16 Jun 2021 11:10:36 +0000 (11:10 +0000)
This ensure we never blunder into indirecting a NULL fsp pointer
in the server. Currently this crashes the server in several info
levels.

Add knownfail.

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

Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Noel Power <npower@samba.org>
selftest/knownfail.d/setpathsymlink [new file with mode: 0644]
source3/selftest/tests.py
source3/torture/proto.h
source3/torture/test_posix.c
source3/torture/torture.c

diff --git a/selftest/knownfail.d/setpathsymlink b/selftest/knownfail.d/setpathsymlink
new file mode 100644 (file)
index 0000000..9d7ded3
--- /dev/null
@@ -0,0 +1,2 @@
+^samba3.smbtorture_s3.crypt.POSIX-SYMLINK-SETPATHINFO.smbtorture\(nt4_dc_smb1\)
+^samba3.smbtorture_s3.plain.POSIX-SYMLINK-SETPATHINFO.smbtorture\(nt4_dc_smb1\)
index c86e6bc9c7d36e12b7d59d7c6288f12a1ec51190..5e9bebdcbce83c35fff1301038543d11e2f3e3f1 100755 (executable)
@@ -267,6 +267,7 @@ posix_tests = ["POSIX", "POSIX-APPEND", "POSIX-SYMLINK-ACL", "POSIX-SYMLINK-EA",
                "POSIX-DIR-DEFAULT-ACL",
                "POSIX-SYMLINK-RENAME",
                "POSIX-SYMLINK-GETPATHINFO",
+               "POSIX-SYMLINK-SETPATHINFO",
               ]
 
 for t in posix_tests:
index 471609d2837f4244ea18d65b65e75f1d391866c0..dfcbd815af095f0b0b390fcd22679ef75d5035e1 100644 (file)
@@ -95,6 +95,7 @@ bool run_posix_dir_default_acl_test(int dummy);
 bool run_case_insensitive_create(int dummy);
 bool run_posix_symlink_rename_test(int dummy);
 bool run_posix_symlink_getpathinfo_test(int dummy);
+bool run_posix_symlink_setpathinfo_test(int dummy);
 
 bool run_nbench2(int dummy);
 bool run_async_echo(int dummy);
index 85e4e6c510f2c348a75c1f967b3287446d1ccf99..20b2b13676110301facee78f958ac097db9ffcaf 100644 (file)
@@ -1694,3 +1694,197 @@ out:
        TALLOC_FREE(frame);
        return correct;
 }
+
+/* List of info levels to try with a POSIX symlink path. */
+
+static struct {
+       uint32_t level;
+       const char *name;
+       uint32_t data_len;
+} posix_smb1_setpath_array[] = {
+  { SMB_SET_FILE_UNIX_BASIC,   "SMB_SET_FILE_UNIX_BASIC",      100},
+  { SMB_SET_FILE_UNIX_INFO2,   "SMB_SET_FILE_UNIX_INFO2",      116},
+  { SMB_SET_FILE_UNIX_LINK,    "SMB_SET_FILE_UNIX_LINK",       8},
+  { SMB_SET_FILE_UNIX_HLINK,   "SMB_SET_FILE_UNIX_HLINK",      8},
+  { SMB_SET_POSIX_ACL,         "SMB_SET_POSIX_ACL",            6},
+  { SMB_SET_POSIX_LOCK,                "SMB_SET_POSIX_LOCK",           24},
+  { SMB_INFO_STANDARD,         "SMB_INFO_STANDARD",            12},
+  { SMB_INFO_SET_EA,           "SMB_INFO_SET_EA",              10},
+  { SMB_FILE_BASIC_INFORMATION, "SMB_FILE_BASIC_INFORMATION",  36},
+  { SMB_SET_FILE_ALLOCATION_INFO, "SMB_SET_FILE_ALLOCATION_INFO", 8},
+  { SMB_SET_FILE_END_OF_FILE_INFO,"SMB_SET_FILE_END_OF_FILE_INFO",8},
+  { SMB_SET_FILE_DISPOSITION_INFO,"SMB_SET_FILE_DISPOSITION_INFO",1},
+  { SMB_FILE_POSITION_INFORMATION,"SMB_FILE_POSITION_INFORMATION",8},
+  { SMB_FILE_FULL_EA_INFORMATION, "SMB_FILE_FULL_EA_INFORMATION",10},
+  { SMB_FILE_MODE_INFORMATION, "SMB_FILE_MODE_INFORMATION",    4},
+  { SMB_FILE_SHORT_NAME_INFORMATION,"SMB_FILE_SHORT_NAME_INFORMATION",12},
+  { SMB_FILE_RENAME_INFORMATION,"SMB_FILE_RENAME_INFORMATION", 20},
+  { SMB_FILE_LINK_INFORMATION, "SMB_FILE_LINK_INFORMATION",    20},
+};
+
+static NTSTATUS do_setpath(TALLOC_CTX *ctx,
+                          struct cli_state *cli_unix,
+                          const char *fname,
+                          size_t i)
+{
+       NTSTATUS status;
+       uint8_t *data = NULL;
+
+       data = talloc_zero_array(ctx,
+                                uint8_t,
+                                posix_smb1_setpath_array[i].data_len);
+       if (data == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       status = cli_setpathinfo(cli_unix,
+                       posix_smb1_setpath_array[i].level,
+                       fname,
+                       data,
+                       posix_smb1_setpath_array[i].data_len);
+       TALLOC_FREE(data);
+
+       /*
+        * We don't care what came back, so long as the
+        * server didn't crash.
+        */
+       if (NT_STATUS_EQUAL(status,
+                       NT_STATUS_CONNECTION_DISCONNECTED)) {
+               printf("cli_setpathinfo info %x (%s) of %s failed"
+                       "error NT_STATUS_CONNECTION_DISCONNECTED\n",
+                       (unsigned int)posix_smb1_setpath_array[i].level,
+                       posix_smb1_setpath_array[i].name,
+                       fname);
+               return status;
+       }
+
+       printf("cli_setpathinfo info %x (%s) of %s got %s "
+               "(this is not an error)\n",
+               (unsigned int)posix_smb1_setpath_array[i].level,
+               posix_smb1_setpath_array[i].name,
+               fname,
+               nt_errstr(status));
+
+       return NT_STATUS_OK;
+}
+
+/*
+  Ensure we can call SMB1 setpathinfo in a symlink,
+  pointing to a real object or dangling. We mostly
+  expect errors, but the server must not crash.
+ */
+bool run_posix_symlink_setpathinfo_test(int dummy)
+{
+       TALLOC_CTX *frame = NULL;
+       struct cli_state *cli_unix = NULL;
+       NTSTATUS status;
+       uint16_t fnum = (uint16_t)-1;
+       const char *fname_real = "file_setpath_real";
+       const char *fname_real_symlink = "file_real_setpath_symlink";
+       const char *nonexist = "nonexist_setpath";
+       const char *nonexist_symlink = "dangling_setpath_symlink";
+       bool correct = false;
+       size_t i;
+
+       frame = talloc_stackframe();
+
+       printf("Starting POSIX-SYMLINK-SETPATHINFO test\n");
+
+       if (!torture_open_connection(&cli_unix, 0)) {
+               TALLOC_FREE(frame);
+               return false;
+       }
+
+       torture_conn_set_sockopt(cli_unix);
+
+       status = torture_setup_unix_extensions(cli_unix);
+       if (!NT_STATUS_IS_OK(status)) {
+               TALLOC_FREE(frame);
+               return false;
+       }
+
+       /* Start with a clean slate. */
+       cli_posix_unlink(cli_unix, fname_real);
+       cli_posix_unlink(cli_unix, fname_real_symlink);
+       cli_posix_unlink(cli_unix, nonexist);
+       cli_posix_unlink(cli_unix, nonexist_symlink);
+
+       /* Create a real file. */
+       status = cli_posix_open(cli_unix,
+                               fname_real,
+                               O_RDWR|O_CREAT,
+                               0644,
+                               &fnum);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("cli_posix_open of %s failed error %s\n",
+                      fname_real,
+                      nt_errstr(status));
+               goto out;
+       }
+       status = cli_close(cli_unix, fnum);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("cli_close failed %s\n", nt_errstr(status));
+               goto out;
+       }
+       fnum = (uint16_t)-1;
+
+       /* Create symlink to real target. */
+       status = cli_posix_symlink(cli_unix,
+                                  fname_real,
+                                  fname_real_symlink);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("cli_posix_symlink of %s -> %s failed error %s\n",
+                      fname_real_symlink,
+                      fname_real,
+                      nt_errstr(status));
+               goto out;
+       }
+
+       /* Now create symlink to non-existing target. */
+       status = cli_posix_symlink(cli_unix,
+                                  nonexist,
+                                  nonexist_symlink);
+       if (!NT_STATUS_IS_OK(status)) {
+               printf("cli_posix_symlink of %s -> %s failed error %s\n",
+                      nonexist_symlink,
+                      nonexist,
+                      nt_errstr(status));
+               goto out;
+       }
+
+       for (i = 0; i < ARRAY_SIZE(posix_smb1_setpath_array); i++) {
+               status = do_setpath(frame,
+                                 cli_unix,
+                                 fname_real_symlink,
+                                 i);
+               if (!NT_STATUS_IS_OK(status)) {
+                       goto out;
+               }
+               status = do_setpath(frame,
+                                 cli_unix,
+                                 nonexist_symlink,
+                                 i);
+               if (!NT_STATUS_IS_OK(status)) {
+                       goto out;
+               }
+       }
+
+       printf("POSIX-SYMLINK-SETPATHINFO test passed\n");
+       correct = true;
+
+out:
+       if (fnum != (uint16_t)-1) {
+               cli_close(cli_unix, fnum);
+       }
+       cli_posix_unlink(cli_unix, fname_real);
+       cli_posix_unlink(cli_unix, fname_real_symlink);
+       cli_posix_unlink(cli_unix, nonexist);
+       cli_posix_unlink(cli_unix, nonexist_symlink);
+
+       if (!torture_close_connection(cli_unix)) {
+               correct = false;
+       }
+
+       TALLOC_FREE(frame);
+       return correct;
+}
index 0187ebf7a439ddc7cdfc1239348f7619e9df267d..892d6d6beabc32bf9118f1333791c5e7f49e75da 100644 (file)
@@ -14967,6 +14967,10 @@ static struct {
                .name  = "POSIX-SYMLINK-GETPATHINFO",
                .fn    = run_posix_symlink_getpathinfo_test,
        },
+       {
+               .name  = "POSIX-SYMLINK-SETPATHINFO",
+               .fn    = run_posix_symlink_setpathinfo_test,
+       },
        {
                .name  = "WINDOWS-BAD-SYMLINK",
                .fn    = run_symlink_open_test,