2
0
mirror of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git synced 2025-09-04 20:19:47 +08:00

Landlock update for v6.17-rc1

-----BEGIN PGP SIGNATURE-----
 
 iIYEABYKAC4WIQSVyBthFV4iTW/VU1/l49DojIL20gUCaINQ2hAcbWljQGRpZ2lr
 b2QubmV0AAoJEOXj0OiMgvbS8DcA/RvnXD7NcvINU94pkY6w+SxtdhsIe/w7EcGF
 LJdwxrKQAP0WpMNTfKdzfe6ub7qE+AkZYhagKAuMCloS1qE35nZgDg==
 =WKRS
 -----END PGP SIGNATURE-----

Merge tag 'landlock-6.17-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/mic/linux

Pull landlock update from Mickaël Salaün:
 "Fix test issues, improve build compatibility, and add new tests"

* tag 'landlock-6.17-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/mic/linux:
  landlock: Fix cosmetic change
  samples/landlock: Fix building on musl libc
  landlock: Fix warning from KUnit tests
  selftests/landlock: Add test to check rule tied to covered mount point
  selftests/landlock: Fix build of audit_test
  selftests/landlock: Fix readlink check
This commit is contained in:
Linus Torvalds 2025-07-28 19:21:32 -07:00
commit ae388edd4a
6 changed files with 92 additions and 31 deletions

View File

@ -13,7 +13,6 @@
#include <errno.h>
#include <fcntl.h>
#include <linux/landlock.h>
#include <linux/prctl.h>
#include <linux/socket.h>
#include <stddef.h>
#include <stdio.h>
@ -25,6 +24,10 @@
#include <unistd.h>
#include <stdbool.h>
#if defined(__GLIBC__)
#include <linux/prctl.h>
#endif
#ifndef landlock_create_ruleset
static inline int
landlock_create_ruleset(const struct landlock_ruleset_attr *const attr,

View File

@ -895,6 +895,7 @@ static bool is_access_to_paths_allowed(
/* Stops when a rule from each layer grants access. */
if (allowed_parent1 && allowed_parent2)
break;
jump_up:
if (walker_path.dentry == walker_path.mnt->mnt_root) {
if (follow_up(&walker_path)) {

View File

@ -119,6 +119,12 @@ static u64 get_id_range(size_t number_of_ids, atomic64_t *const counter,
#ifdef CONFIG_SECURITY_LANDLOCK_KUNIT_TEST
static u8 get_random_u8_positive(void)
{
/* max() evaluates its arguments once. */
return max(1, get_random_u8());
}
static void test_range1_rand0(struct kunit *const test)
{
atomic64_t counter;
@ -127,8 +133,9 @@ static void test_range1_rand0(struct kunit *const test)
init = get_random_u32();
atomic64_set(&counter, init);
KUNIT_EXPECT_EQ(test, get_id_range(1, &counter, 0), init);
KUNIT_EXPECT_EQ(
test, get_id_range(get_random_u8(), &counter, get_random_u8()),
KUNIT_EXPECT_EQ(test,
get_id_range(get_random_u8_positive(), &counter,
get_random_u8()),
init + 1);
}
@ -140,8 +147,9 @@ static void test_range1_rand1(struct kunit *const test)
init = get_random_u32();
atomic64_set(&counter, init);
KUNIT_EXPECT_EQ(test, get_id_range(1, &counter, 1), init);
KUNIT_EXPECT_EQ(
test, get_id_range(get_random_u8(), &counter, get_random_u8()),
KUNIT_EXPECT_EQ(test,
get_id_range(get_random_u8_positive(), &counter,
get_random_u8()),
init + 2);
}
@ -153,8 +161,9 @@ static void test_range1_rand15(struct kunit *const test)
init = get_random_u32();
atomic64_set(&counter, init);
KUNIT_EXPECT_EQ(test, get_id_range(1, &counter, 15), init);
KUNIT_EXPECT_EQ(
test, get_id_range(get_random_u8(), &counter, get_random_u8()),
KUNIT_EXPECT_EQ(test,
get_id_range(get_random_u8_positive(), &counter,
get_random_u8()),
init + 16);
}
@ -166,8 +175,9 @@ static void test_range1_rand16(struct kunit *const test)
init = get_random_u32();
atomic64_set(&counter, init);
KUNIT_EXPECT_EQ(test, get_id_range(1, &counter, 16), init);
KUNIT_EXPECT_EQ(
test, get_id_range(get_random_u8(), &counter, get_random_u8()),
KUNIT_EXPECT_EQ(test,
get_id_range(get_random_u8_positive(), &counter,
get_random_u8()),
init + 1);
}
@ -179,8 +189,9 @@ static void test_range2_rand0(struct kunit *const test)
init = get_random_u32();
atomic64_set(&counter, init);
KUNIT_EXPECT_EQ(test, get_id_range(2, &counter, 0), init);
KUNIT_EXPECT_EQ(
test, get_id_range(get_random_u8(), &counter, get_random_u8()),
KUNIT_EXPECT_EQ(test,
get_id_range(get_random_u8_positive(), &counter,
get_random_u8()),
init + 2);
}
@ -192,8 +203,9 @@ static void test_range2_rand1(struct kunit *const test)
init = get_random_u32();
atomic64_set(&counter, init);
KUNIT_EXPECT_EQ(test, get_id_range(2, &counter, 1), init);
KUNIT_EXPECT_EQ(
test, get_id_range(get_random_u8(), &counter, get_random_u8()),
KUNIT_EXPECT_EQ(test,
get_id_range(get_random_u8_positive(), &counter,
get_random_u8()),
init + 3);
}
@ -205,8 +217,9 @@ static void test_range2_rand2(struct kunit *const test)
init = get_random_u32();
atomic64_set(&counter, init);
KUNIT_EXPECT_EQ(test, get_id_range(2, &counter, 2), init);
KUNIT_EXPECT_EQ(
test, get_id_range(get_random_u8(), &counter, get_random_u8()),
KUNIT_EXPECT_EQ(test,
get_id_range(get_random_u8_positive(), &counter,
get_random_u8()),
init + 4);
}
@ -218,8 +231,9 @@ static void test_range2_rand15(struct kunit *const test)
init = get_random_u32();
atomic64_set(&counter, init);
KUNIT_EXPECT_EQ(test, get_id_range(2, &counter, 15), init);
KUNIT_EXPECT_EQ(
test, get_id_range(get_random_u8(), &counter, get_random_u8()),
KUNIT_EXPECT_EQ(test,
get_id_range(get_random_u8_positive(), &counter,
get_random_u8()),
init + 17);
}
@ -231,8 +245,9 @@ static void test_range2_rand16(struct kunit *const test)
init = get_random_u32();
atomic64_set(&counter, init);
KUNIT_EXPECT_EQ(test, get_id_range(2, &counter, 16), init);
KUNIT_EXPECT_EQ(
test, get_id_range(get_random_u8(), &counter, get_random_u8()),
KUNIT_EXPECT_EQ(test,
get_id_range(get_random_u8_positive(), &counter,
get_random_u8()),
init + 2);
}

View File

@ -403,11 +403,12 @@ static int audit_init_filter_exe(struct audit_filter *filter, const char *path)
/* It is assume that there is not already filtering rules. */
filter->record_type = AUDIT_EXE;
if (!path) {
filter->exe_len = readlink("/proc/self/exe", filter->exe,
int ret = readlink("/proc/self/exe", filter->exe,
sizeof(filter->exe) - 1);
if (filter->exe_len < 0)
if (ret < 0)
return -errno;
filter->exe_len = ret;
return 0;
}

View File

@ -7,6 +7,7 @@
#define _GNU_SOURCE
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <linux/landlock.h>
#include <pthread.h>

View File

@ -1832,6 +1832,46 @@ TEST_F_FORK(layout1, release_inodes)
ASSERT_EQ(ENOENT, test_open(dir_s3d3, O_RDONLY));
}
/*
* This test checks that a rule on a directory used as a mount point does not
* grant access to the mount covering it. It is a generalization of the bind
* mount case in layout3_fs.hostfs.release_inodes that tests hidden mount points.
*/
TEST_F_FORK(layout1, covered_rule)
{
const struct rule layer1[] = {
{
.path = dir_s3d2,
.access = LANDLOCK_ACCESS_FS_READ_DIR,
},
{},
};
int ruleset_fd;
/* Unmount to simplify FIXTURE_TEARDOWN. */
set_cap(_metadata, CAP_SYS_ADMIN);
ASSERT_EQ(0, umount(dir_s3d2));
clear_cap(_metadata, CAP_SYS_ADMIN);
/* Creates a ruleset with the future hidden directory. */
ruleset_fd =
create_ruleset(_metadata, LANDLOCK_ACCESS_FS_READ_DIR, layer1);
ASSERT_LE(0, ruleset_fd);
/* Covers with a new mount point. */
set_cap(_metadata, CAP_SYS_ADMIN);
ASSERT_EQ(0, mount_opt(&mnt_tmp, dir_s3d2));
clear_cap(_metadata, CAP_SYS_ADMIN);
ASSERT_EQ(0, test_open(dir_s3d2, O_RDONLY));
enforce_ruleset(_metadata, ruleset_fd);
ASSERT_EQ(0, close(ruleset_fd));
/* Checks that access to the new mount point is denied. */
ASSERT_EQ(EACCES, test_open(dir_s3d2, O_RDONLY));
}
enum relative_access {
REL_OPEN,
REL_CHDIR,