Skip to content

Commit 589172e

Browse files
committed
landlock: Change landlock_add_rule(2) argument check ordering
This makes more sense to first check the ruleset FD and then the rule attribute. It will be useful to factor out code for other rule types. Add inval_add_rule_arguments tests, extension of empty_path_beneath_attr tests, to also check error ordering for landlock_add_rule(2). Link: https://lore.kernel.org/r/20220506160820.524344-9-mic@digikod.net Cc: stable@vger.kernel.org Signed-off-by: Mickaël Salaün <mic@digikod.net>
1 parent d1788ad commit 589172e

2 files changed

Lines changed: 45 additions & 11 deletions

File tree

security/landlock/syscalls.c

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -318,20 +318,24 @@ SYSCALL_DEFINE4(landlock_add_rule, const int, ruleset_fd,
318318
if (flags)
319319
return -EINVAL;
320320

321-
if (rule_type != LANDLOCK_RULE_PATH_BENEATH)
322-
return -EINVAL;
323-
324-
/* Copies raw user space buffer, only one type for now. */
325-
res = copy_from_user(&path_beneath_attr, rule_attr,
326-
sizeof(path_beneath_attr));
327-
if (res)
328-
return -EFAULT;
329-
330321
/* Gets and checks the ruleset. */
331322
ruleset = get_ruleset_from_fd(ruleset_fd, FMODE_CAN_WRITE);
332323
if (IS_ERR(ruleset))
333324
return PTR_ERR(ruleset);
334325

326+
if (rule_type != LANDLOCK_RULE_PATH_BENEATH) {
327+
err = -EINVAL;
328+
goto out_put_ruleset;
329+
}
330+
331+
/* Copies raw user space buffer, only one type for now. */
332+
res = copy_from_user(&path_beneath_attr, rule_attr,
333+
sizeof(path_beneath_attr));
334+
if (res) {
335+
err = -EFAULT;
336+
goto out_put_ruleset;
337+
}
338+
335339
/*
336340
* Informs about useless rule: empty allowed_access (i.e. deny rules)
337341
* are ignored in path walks.

tools/testing/selftests/landlock/base_test.c

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,20 +121,50 @@ TEST(inval_create_ruleset_flags)
121121
ASSERT_EQ(EINVAL, errno);
122122
}
123123

124-
TEST(empty_path_beneath_attr)
124+
/* Tests ordering of syscall argument checks. */
125+
TEST(add_rule_checks_ordering)
125126
{
126127
const struct landlock_ruleset_attr ruleset_attr = {
127128
.handled_access_fs = LANDLOCK_ACCESS_FS_EXECUTE,
128129
};
130+
struct landlock_path_beneath_attr path_beneath_attr = {
131+
.allowed_access = LANDLOCK_ACCESS_FS_EXECUTE,
132+
.parent_fd = -1,
133+
};
129134
const int ruleset_fd =
130135
landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
131136

132137
ASSERT_LE(0, ruleset_fd);
133138

134-
/* Similar to struct landlock_path_beneath_attr.parent_fd = 0 */
139+
/* Checks invalid flags. */
140+
ASSERT_EQ(-1, landlock_add_rule(-1, 0, NULL, 1));
141+
ASSERT_EQ(EINVAL, errno);
142+
143+
/* Checks invalid ruleset FD. */
144+
ASSERT_EQ(-1, landlock_add_rule(-1, 0, NULL, 0));
145+
ASSERT_EQ(EBADF, errno);
146+
147+
/* Checks invalid rule type. */
148+
ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, 0, NULL, 0));
149+
ASSERT_EQ(EINVAL, errno);
150+
151+
/* Checks invalid rule attr. */
135152
ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
136153
NULL, 0));
137154
ASSERT_EQ(EFAULT, errno);
155+
156+
/* Checks invalid path_beneath.parent_fd. */
157+
ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
158+
&path_beneath_attr, 0));
159+
ASSERT_EQ(EBADF, errno);
160+
161+
/* Checks valid call. */
162+
path_beneath_attr.parent_fd =
163+
open("/tmp", O_PATH | O_NOFOLLOW | O_DIRECTORY | O_CLOEXEC);
164+
ASSERT_LE(0, path_beneath_attr.parent_fd);
165+
ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
166+
&path_beneath_attr, 0));
167+
ASSERT_EQ(0, close(path_beneath_attr.parent_fd));
138168
ASSERT_EQ(0, close(ruleset_fd));
139169
}
140170

0 commit comments

Comments
 (0)