Skip to content

Commit eba39ca

Browse files
committed
landlock: Change landlock_restrict_self(2) check ordering
According to the Landlock goal to be a security feature available to unprivileges processes, it makes more sense to first check for no_new_privs before checking anything else (i.e. syscall arguments). Merge inval_fd_enforce and unpriv_enforce_without_no_new_privs tests into the new restrict_self_checks_ordering. This is similar to the previous commit checking other syscalls. Link: https://lore.kernel.org/r/20220506160820.524344-10-mic@digikod.net Cc: stable@vger.kernel.org Signed-off-by: Mickaël Salaün <mic@digikod.net>
1 parent 589172e commit eba39ca

2 files changed

Lines changed: 41 additions & 14 deletions

File tree

security/landlock/syscalls.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -405,10 +405,6 @@ SYSCALL_DEFINE2(landlock_restrict_self, const int, ruleset_fd, const __u32,
405405
if (!landlock_initialized)
406406
return -EOPNOTSUPP;
407407

408-
/* No flag for now. */
409-
if (flags)
410-
return -EINVAL;
411-
412408
/*
413409
* Similar checks as for seccomp(2), except that an -EPERM may be
414410
* returned.
@@ -417,6 +413,10 @@ SYSCALL_DEFINE2(landlock_restrict_self, const int, ruleset_fd, const __u32,
417413
!ns_capable_noaudit(current_user_ns(), CAP_SYS_ADMIN))
418414
return -EPERM;
419415

416+
/* No flag for now. */
417+
if (flags)
418+
return -EINVAL;
419+
420420
/* Gets and checks the ruleset. */
421421
ruleset = get_ruleset_from_fd(ruleset_fd, FMODE_CAN_READ);
422422
if (IS_ERR(ruleset))

tools/testing/selftests/landlock/base_test.c

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -168,22 +168,49 @@ TEST(add_rule_checks_ordering)
168168
ASSERT_EQ(0, close(ruleset_fd));
169169
}
170170

171-
TEST(inval_fd_enforce)
171+
/* Tests ordering of syscall argument and permission checks. */
172+
TEST(restrict_self_checks_ordering)
172173
{
174+
const struct landlock_ruleset_attr ruleset_attr = {
175+
.handled_access_fs = LANDLOCK_ACCESS_FS_EXECUTE,
176+
};
177+
struct landlock_path_beneath_attr path_beneath_attr = {
178+
.allowed_access = LANDLOCK_ACCESS_FS_EXECUTE,
179+
.parent_fd = -1,
180+
};
181+
const int ruleset_fd =
182+
landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
183+
184+
ASSERT_LE(0, ruleset_fd);
185+
path_beneath_attr.parent_fd =
186+
open("/tmp", O_PATH | O_NOFOLLOW | O_DIRECTORY | O_CLOEXEC);
187+
ASSERT_LE(0, path_beneath_attr.parent_fd);
188+
ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
189+
&path_beneath_attr, 0));
190+
ASSERT_EQ(0, close(path_beneath_attr.parent_fd));
191+
192+
/* Checks unprivileged enforcement without no_new_privs. */
193+
drop_caps(_metadata);
194+
ASSERT_EQ(-1, landlock_restrict_self(-1, -1));
195+
ASSERT_EQ(EPERM, errno);
196+
ASSERT_EQ(-1, landlock_restrict_self(-1, 0));
197+
ASSERT_EQ(EPERM, errno);
198+
ASSERT_EQ(-1, landlock_restrict_self(ruleset_fd, 0));
199+
ASSERT_EQ(EPERM, errno);
200+
173201
ASSERT_EQ(0, prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0));
174202

203+
/* Checks invalid flags. */
204+
ASSERT_EQ(-1, landlock_restrict_self(-1, -1));
205+
ASSERT_EQ(EINVAL, errno);
206+
207+
/* Checks invalid ruleset FD. */
175208
ASSERT_EQ(-1, landlock_restrict_self(-1, 0));
176209
ASSERT_EQ(EBADF, errno);
177-
}
178-
179-
TEST(unpriv_enforce_without_no_new_privs)
180-
{
181-
int err;
182210

183-
drop_caps(_metadata);
184-
err = landlock_restrict_self(-1, 0);
185-
ASSERT_EQ(EPERM, errno);
186-
ASSERT_EQ(err, -1);
211+
/* Checks valid call. */
212+
ASSERT_EQ(0, landlock_restrict_self(ruleset_fd, 0));
213+
ASSERT_EQ(0, close(ruleset_fd));
187214
}
188215

189216
TEST(ruleset_fd_io)

0 commit comments

Comments
 (0)