Commit 6a1bdd4a authored by Mickaël Salaün's avatar Mickaël Salaün

selftests/landlock: Fully test file rename with "remove" access

These tests were missing to check the check_access_path() call with all
combinations of maybe_remove(old_dentry) and maybe_remove(new_dentry).

Extend layout1.link with a new complementary test and check that
REMOVE_FILE is not required to link a file.

Cc: Shuah Khan <shuah@kernel.org>
Link: https://lore.kernel.org/r/20220506160820.524344-7-mic@digikod.net
Cc: stable@vger.kernel.org
Signed-off-by: default avatarMickaël Salaün <mic@digikod.net>
parent d18955d0
...@@ -1659,15 +1659,21 @@ TEST_F_FORK(layout1, execute) ...@@ -1659,15 +1659,21 @@ TEST_F_FORK(layout1, execute)
TEST_F_FORK(layout1, link) TEST_F_FORK(layout1, link)
{ {
const struct rule rules[] = { const struct rule layer1[] = {
{ {
.path = dir_s1d2, .path = dir_s1d2,
.access = LANDLOCK_ACCESS_FS_MAKE_REG, .access = LANDLOCK_ACCESS_FS_MAKE_REG,
}, },
{}, {},
}; };
const int ruleset_fd = const struct rule layer2[] = {
create_ruleset(_metadata, rules[0].access, rules); {
.path = dir_s1d3,
.access = LANDLOCK_ACCESS_FS_REMOVE_FILE,
},
{},
};
int ruleset_fd = create_ruleset(_metadata, layer1[0].access, layer1);
ASSERT_LE(0, ruleset_fd); ASSERT_LE(0, ruleset_fd);
...@@ -1680,14 +1686,30 @@ TEST_F_FORK(layout1, link) ...@@ -1680,14 +1686,30 @@ TEST_F_FORK(layout1, link)
ASSERT_EQ(-1, link(file2_s1d1, file1_s1d1)); ASSERT_EQ(-1, link(file2_s1d1, file1_s1d1));
ASSERT_EQ(EACCES, errno); ASSERT_EQ(EACCES, errno);
/* Denies linking because of reparenting. */ /* Denies linking because of reparenting. */
ASSERT_EQ(-1, link(file1_s2d1, file1_s1d2)); ASSERT_EQ(-1, link(file1_s2d1, file1_s1d2));
ASSERT_EQ(EXDEV, errno); ASSERT_EQ(EXDEV, errno);
ASSERT_EQ(-1, link(file2_s1d2, file1_s1d3)); ASSERT_EQ(-1, link(file2_s1d2, file1_s1d3));
ASSERT_EQ(EXDEV, errno); ASSERT_EQ(EXDEV, errno);
ASSERT_EQ(-1, link(file2_s1d3, file1_s1d2));
ASSERT_EQ(EXDEV, errno);
ASSERT_EQ(0, link(file2_s1d2, file1_s1d2)); ASSERT_EQ(0, link(file2_s1d2, file1_s1d2));
ASSERT_EQ(0, link(file2_s1d3, file1_s1d3)); ASSERT_EQ(0, link(file2_s1d3, file1_s1d3));
/* Prepares for next unlinks. */
ASSERT_EQ(0, unlink(file2_s1d2));
ASSERT_EQ(0, unlink(file2_s1d3));
ruleset_fd = create_ruleset(_metadata, layer2[0].access, layer2);
ASSERT_LE(0, ruleset_fd);
enforce_ruleset(_metadata, ruleset_fd);
ASSERT_EQ(0, close(ruleset_fd));
/* Checks that linkind doesn't require the ability to delete a file. */
ASSERT_EQ(0, link(file1_s1d2, file2_s1d2));
ASSERT_EQ(0, link(file1_s1d3, file2_s1d3));
} }
TEST_F_FORK(layout1, rename_file) TEST_F_FORK(layout1, rename_file)
...@@ -1708,7 +1730,6 @@ TEST_F_FORK(layout1, rename_file) ...@@ -1708,7 +1730,6 @@ TEST_F_FORK(layout1, rename_file)
ASSERT_LE(0, ruleset_fd); ASSERT_LE(0, ruleset_fd);
ASSERT_EQ(0, unlink(file1_s1d1));
ASSERT_EQ(0, unlink(file1_s1d2)); ASSERT_EQ(0, unlink(file1_s1d2));
enforce_ruleset(_metadata, ruleset_fd); enforce_ruleset(_metadata, ruleset_fd);
...@@ -1744,9 +1765,15 @@ TEST_F_FORK(layout1, rename_file) ...@@ -1744,9 +1765,15 @@ TEST_F_FORK(layout1, rename_file)
ASSERT_EQ(-1, renameat2(AT_FDCWD, dir_s2d2, AT_FDCWD, file1_s2d1, ASSERT_EQ(-1, renameat2(AT_FDCWD, dir_s2d2, AT_FDCWD, file1_s2d1,
RENAME_EXCHANGE)); RENAME_EXCHANGE));
ASSERT_EQ(EACCES, errno); ASSERT_EQ(EACCES, errno);
/* Checks that file1_s2d1 cannot be removed (instead of ENOTDIR). */
ASSERT_EQ(-1, rename(dir_s2d2, file1_s2d1));
ASSERT_EQ(EACCES, errno);
ASSERT_EQ(-1, renameat2(AT_FDCWD, file1_s2d1, AT_FDCWD, dir_s2d2, ASSERT_EQ(-1, renameat2(AT_FDCWD, file1_s2d1, AT_FDCWD, dir_s2d2,
RENAME_EXCHANGE)); RENAME_EXCHANGE));
ASSERT_EQ(EACCES, errno); ASSERT_EQ(EACCES, errno);
/* Checks that file1_s1d1 cannot be removed (instead of EISDIR). */
ASSERT_EQ(-1, rename(file1_s1d1, dir_s1d2));
ASSERT_EQ(EACCES, errno);
/* Renames files with different parents. */ /* Renames files with different parents. */
ASSERT_EQ(-1, rename(file1_s2d2, file1_s1d2)); ASSERT_EQ(-1, rename(file1_s2d2, file1_s1d2));
...@@ -1809,9 +1836,15 @@ TEST_F_FORK(layout1, rename_dir) ...@@ -1809,9 +1836,15 @@ TEST_F_FORK(layout1, rename_dir)
ASSERT_EQ(-1, renameat2(AT_FDCWD, dir_s1d1, AT_FDCWD, dir_s2d1, ASSERT_EQ(-1, renameat2(AT_FDCWD, dir_s1d1, AT_FDCWD, dir_s2d1,
RENAME_EXCHANGE)); RENAME_EXCHANGE));
ASSERT_EQ(EACCES, errno); ASSERT_EQ(EACCES, errno);
/* Checks that dir_s1d2 cannot be removed (instead of ENOTDIR). */
ASSERT_EQ(-1, rename(dir_s1d2, file1_s1d1));
ASSERT_EQ(EACCES, errno);
ASSERT_EQ(-1, renameat2(AT_FDCWD, file1_s1d1, AT_FDCWD, dir_s1d2, ASSERT_EQ(-1, renameat2(AT_FDCWD, file1_s1d1, AT_FDCWD, dir_s1d2,
RENAME_EXCHANGE)); RENAME_EXCHANGE));
ASSERT_EQ(EACCES, errno); ASSERT_EQ(EACCES, errno);
/* Checks that dir_s1d2 cannot be removed (instead of EISDIR). */
ASSERT_EQ(-1, rename(file1_s1d1, dir_s1d2));
ASSERT_EQ(EACCES, errno);
/* /*
* Exchanges and renames directory to the same parent, which allows * Exchanges and renames directory to the same parent, which allows
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment