Skip to content

Commit 6a1bdd4

Browse files
committed
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: Mickaël Salaün <mic@digikod.net>
1 parent d18955d commit 6a1bdd4

1 file changed

Lines changed: 37 additions & 4 deletions

File tree

tools/testing/selftests/landlock/fs_test.c

Lines changed: 37 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1659,15 +1659,21 @@ TEST_F_FORK(layout1, execute)
16591659

16601660
TEST_F_FORK(layout1, link)
16611661
{
1662-
const struct rule rules[] = {
1662+
const struct rule layer1[] = {
16631663
{
16641664
.path = dir_s1d2,
16651665
.access = LANDLOCK_ACCESS_FS_MAKE_REG,
16661666
},
16671667
{},
16681668
};
1669-
const int ruleset_fd =
1670-
create_ruleset(_metadata, rules[0].access, rules);
1669+
const struct rule layer2[] = {
1670+
{
1671+
.path = dir_s1d3,
1672+
.access = LANDLOCK_ACCESS_FS_REMOVE_FILE,
1673+
},
1674+
{},
1675+
};
1676+
int ruleset_fd = create_ruleset(_metadata, layer1[0].access, layer1);
16711677

16721678
ASSERT_LE(0, ruleset_fd);
16731679

@@ -1680,14 +1686,30 @@ TEST_F_FORK(layout1, link)
16801686

16811687
ASSERT_EQ(-1, link(file2_s1d1, file1_s1d1));
16821688
ASSERT_EQ(EACCES, errno);
1689+
16831690
/* Denies linking because of reparenting. */
16841691
ASSERT_EQ(-1, link(file1_s2d1, file1_s1d2));
16851692
ASSERT_EQ(EXDEV, errno);
16861693
ASSERT_EQ(-1, link(file2_s1d2, file1_s1d3));
16871694
ASSERT_EQ(EXDEV, errno);
1695+
ASSERT_EQ(-1, link(file2_s1d3, file1_s1d2));
1696+
ASSERT_EQ(EXDEV, errno);
16881697

16891698
ASSERT_EQ(0, link(file2_s1d2, file1_s1d2));
16901699
ASSERT_EQ(0, link(file2_s1d3, file1_s1d3));
1700+
1701+
/* Prepares for next unlinks. */
1702+
ASSERT_EQ(0, unlink(file2_s1d2));
1703+
ASSERT_EQ(0, unlink(file2_s1d3));
1704+
1705+
ruleset_fd = create_ruleset(_metadata, layer2[0].access, layer2);
1706+
ASSERT_LE(0, ruleset_fd);
1707+
enforce_ruleset(_metadata, ruleset_fd);
1708+
ASSERT_EQ(0, close(ruleset_fd));
1709+
1710+
/* Checks that linkind doesn't require the ability to delete a file. */
1711+
ASSERT_EQ(0, link(file1_s1d2, file2_s1d2));
1712+
ASSERT_EQ(0, link(file1_s1d3, file2_s1d3));
16911713
}
16921714

16931715
TEST_F_FORK(layout1, rename_file)
@@ -1708,7 +1730,6 @@ TEST_F_FORK(layout1, rename_file)
17081730

17091731
ASSERT_LE(0, ruleset_fd);
17101732

1711-
ASSERT_EQ(0, unlink(file1_s1d1));
17121733
ASSERT_EQ(0, unlink(file1_s1d2));
17131734

17141735
enforce_ruleset(_metadata, ruleset_fd);
@@ -1744,9 +1765,15 @@ TEST_F_FORK(layout1, rename_file)
17441765
ASSERT_EQ(-1, renameat2(AT_FDCWD, dir_s2d2, AT_FDCWD, file1_s2d1,
17451766
RENAME_EXCHANGE));
17461767
ASSERT_EQ(EACCES, errno);
1768+
/* Checks that file1_s2d1 cannot be removed (instead of ENOTDIR). */
1769+
ASSERT_EQ(-1, rename(dir_s2d2, file1_s2d1));
1770+
ASSERT_EQ(EACCES, errno);
17471771
ASSERT_EQ(-1, renameat2(AT_FDCWD, file1_s2d1, AT_FDCWD, dir_s2d2,
17481772
RENAME_EXCHANGE));
17491773
ASSERT_EQ(EACCES, errno);
1774+
/* Checks that file1_s1d1 cannot be removed (instead of EISDIR). */
1775+
ASSERT_EQ(-1, rename(file1_s1d1, dir_s1d2));
1776+
ASSERT_EQ(EACCES, errno);
17501777

17511778
/* Renames files with different parents. */
17521779
ASSERT_EQ(-1, rename(file1_s2d2, file1_s1d2));
@@ -1809,9 +1836,15 @@ TEST_F_FORK(layout1, rename_dir)
18091836
ASSERT_EQ(-1, renameat2(AT_FDCWD, dir_s1d1, AT_FDCWD, dir_s2d1,
18101837
RENAME_EXCHANGE));
18111838
ASSERT_EQ(EACCES, errno);
1839+
/* Checks that dir_s1d2 cannot be removed (instead of ENOTDIR). */
1840+
ASSERT_EQ(-1, rename(dir_s1d2, file1_s1d1));
1841+
ASSERT_EQ(EACCES, errno);
18121842
ASSERT_EQ(-1, renameat2(AT_FDCWD, file1_s1d1, AT_FDCWD, dir_s1d2,
18131843
RENAME_EXCHANGE));
18141844
ASSERT_EQ(EACCES, errno);
1845+
/* Checks that dir_s1d2 cannot be removed (instead of EISDIR). */
1846+
ASSERT_EQ(-1, rename(file1_s1d1, dir_s1d2));
1847+
ASSERT_EQ(EACCES, errno);
18151848

18161849
/*
18171850
* Exchanges and renames directory to the same parent, which allows

0 commit comments

Comments
 (0)