From 249565c65af05fb88e15ed10d0ff770c97c938ff Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 19 Apr 2021 16:25:51 -0700 Subject: [PATCH] s3: torture: Add samba3.smbtorture_s3.plain.POSIX-SYMLINK-CHMOD Shows we must protect against a null fsp handle when doing POSIX chmod on a symlink, whether the symlink points to a real object or is dangling. Add to knownfail for now. Commit 9722732b1867e359304594ada72ff40cd1341be5 removed the fsp == NULL protection for POSIX, and we need to put it back. Signed-off-by: Jeremy Allison Reviewed-by: Andreas Schneider --- selftest/knownfail.d/symlink_chmod | 2 + source3/selftest/tests.py | 1 + source3/torture/proto.h | 1 + source3/torture/test_posix.c | 137 +++++++++++++++++++++++++++++ source3/torture/torture.c | 4 + 5 files changed, 145 insertions(+) create mode 100644 selftest/knownfail.d/symlink_chmod diff --git a/selftest/knownfail.d/symlink_chmod b/selftest/knownfail.d/symlink_chmod new file mode 100644 index 00000000000..8ebe2a7cf9e --- /dev/null +++ b/selftest/knownfail.d/symlink_chmod @@ -0,0 +1,2 @@ +^samba3.smbtorture_s3.plain.*POSIX-SYMLINK-CHMOD +^samba3.smbtorture_s3.crypt.*POSIX-SYMLINK-CHMOD diff --git a/source3/selftest/tests.py b/source3/selftest/tests.py index 6cbed8cc8e2..11d0a41bda9 100755 --- a/source3/selftest/tests.py +++ b/source3/selftest/tests.py @@ -263,6 +263,7 @@ posix_tests = ["POSIX", "POSIX-APPEND", "POSIX-SYMLINK-ACL", "POSIX-SYMLINK-EA", "POSIX-READLINK", "POSIX-STAT", "POSIX-SYMLINK-PARENT", + "POSIX-SYMLINK-CHMOD", ] for t in posix_tests: diff --git a/source3/torture/proto.h b/source3/torture/proto.h index dc27467ba64..57b1b5fea13 100644 --- a/source3/torture/proto.h +++ b/source3/torture/proto.h @@ -90,6 +90,7 @@ bool run_posix_ls_single_test(int dummy); bool run_posix_readlink_test(int dummy); bool run_posix_stat_test(int dummy); bool run_posix_symlink_parent_test(int dummy); +bool run_posix_symlink_chmod_test(int dummy); bool run_case_insensitive_create(int dummy); bool run_nbench2(int dummy); diff --git a/source3/torture/test_posix.c b/source3/torture/test_posix.c index c2ce392ca76..33a28866f9f 100644 --- a/source3/torture/test_posix.c +++ b/source3/torture/test_posix.c @@ -911,4 +911,141 @@ out: return correct; } +/* + Ensure we get an error when doing chmod on a symlink, + whether it is pointing to a real object or dangling. + */ +bool run_posix_symlink_chmod_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_real"; + const char *fname_real_symlink = "file_real_symlink"; + const char *nonexist = "nonexist"; + const char *nonexist_symlink = "dangling_symlink"; + bool correct = false; + + frame = talloc_stackframe(); + + printf("Starting POSIX-SYMLINK-CHMOD 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; + } + + /* We should not be able to chmod symlinks that point to something. */ + status = cli_posix_chmod(cli_unix, fname_real_symlink, 0777); + + /* This should fail with something other than server crashed. */ + if (NT_STATUS_IS_OK(status)) { + printf("cli_posix_chmod of %s succeeded (should have failed)\n", + fname_real_symlink); + goto out; + } + if (NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_DISCONNECTED)) { + /* Oops. Server crashed. */ + printf("cli_posix_chmod of %s failed error %s\n", + fname_real_symlink, + nt_errstr(status)); + goto out; + } + /* Any other failure is ok. */ + /* 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; + } + + /* We should not be able to chmod symlinks that point to nothing. */ + status = cli_posix_chmod(cli_unix, nonexist_symlink, 0777); + + /* This should fail with something other than server crashed. */ + if (NT_STATUS_IS_OK(status)) { + printf("cli_posix_chmod of %s succeeded (should have failed)\n", + nonexist_symlink); + goto out; + } + if (NT_STATUS_EQUAL(status, NT_STATUS_CONNECTION_DISCONNECTED)) { + /* Oops. Server crashed. */ + printf("cli_posix_chmod of %s failed error %s\n", + nonexist_symlink, + nt_errstr(status)); + goto out; + } + + /* Any other failure is ok. */ + printf("POSIX-SYMLINK-CHMOD test passed (expected failure was %s)\n", + nt_errstr(status)); + 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; +} diff --git a/source3/torture/torture.c b/source3/torture/torture.c index a46a252bc19..68e2cd2ba20 100644 --- a/source3/torture/torture.c +++ b/source3/torture/torture.c @@ -14951,6 +14951,10 @@ static struct { .name = "POSIX-SYMLINK-PARENT", .fn = run_posix_symlink_parent_test, }, + { + .name = "POSIX-SYMLINK-CHMOD", + .fn = run_posix_symlink_chmod_test, + }, { .name = "WINDOWS-BAD-SYMLINK", .fn = run_symlink_open_test, -- 2.47.3