Commit 6004b044 authored by Linus Torvalds's avatar Linus Torvalds
Browse files
Pull landlock test fixes from Mickaël Salaün:
 "Fix build issues for tests, and improve test compatibility"

* tag 'landlock-6.8-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/mic/linux:
  selftests/landlock: Fix capability for net_test
  selftests/landlock: Fix fs_test build with old libc
  selftests/landlock: Fix net_test build with old libc
parents 1f3a3e2a bb6f4dbe
Loading
Loading
Loading
Loading
+40 −8
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@

#include <errno.h>
#include <linux/landlock.h>
#include <linux/securebits.h>
#include <sys/capability.h>
#include <sys/socket.h>
#include <sys/syscall.h>
@@ -115,11 +116,16 @@ static void _init_caps(struct __test_metadata *const _metadata, bool drop_all)
		/* clang-format off */
		CAP_DAC_OVERRIDE,
		CAP_MKNOD,
		CAP_NET_ADMIN,
		CAP_NET_BIND_SERVICE,
		CAP_SYS_ADMIN,
		CAP_SYS_CHROOT,
		CAP_NET_BIND_SERVICE,
		/* clang-format on */
	};
	const unsigned int noroot = SECBIT_NOROOT | SECBIT_NOROOT_LOCKED;

	if ((cap_get_secbits() & noroot) != noroot)
		EXPECT_EQ(0, cap_set_secbits(noroot));

	cap_p = cap_get_proc();
	EXPECT_NE(NULL, cap_p)
@@ -137,6 +143,8 @@ static void _init_caps(struct __test_metadata *const _metadata, bool drop_all)
			TH_LOG("Failed to cap_set_flag: %s", strerror(errno));
		}
	}

	/* Automatically resets ambient capabilities. */
	EXPECT_NE(-1, cap_set_proc(cap_p))
	{
		TH_LOG("Failed to cap_set_proc: %s", strerror(errno));
@@ -145,6 +153,9 @@ static void _init_caps(struct __test_metadata *const _metadata, bool drop_all)
	{
		TH_LOG("Failed to cap_free: %s", strerror(errno));
	}

	/* Quickly checks that ambient capabilities are cleared. */
	EXPECT_NE(-1, cap_get_ambient(caps[0]));
}

/* We cannot put such helpers in a library because of kselftest_harness.h . */
@@ -158,8 +169,9 @@ static void __maybe_unused drop_caps(struct __test_metadata *const _metadata)
	_init_caps(_metadata, true);
}

static void _effective_cap(struct __test_metadata *const _metadata,
			   const cap_value_t caps, const cap_flag_value_t value)
static void _change_cap(struct __test_metadata *const _metadata,
			const cap_flag_t flag, const cap_value_t cap,
			const cap_flag_value_t value)
{
	cap_t cap_p;

@@ -168,7 +180,7 @@ static void _effective_cap(struct __test_metadata *const _metadata,
	{
		TH_LOG("Failed to cap_get_proc: %s", strerror(errno));
	}
	EXPECT_NE(-1, cap_set_flag(cap_p, CAP_EFFECTIVE, 1, &caps, value))
	EXPECT_NE(-1, cap_set_flag(cap_p, flag, 1, &cap, value))
	{
		TH_LOG("Failed to cap_set_flag: %s", strerror(errno));
	}
@@ -183,15 +195,35 @@ static void _effective_cap(struct __test_metadata *const _metadata,
}

static void __maybe_unused set_cap(struct __test_metadata *const _metadata,
				   const cap_value_t caps)
				   const cap_value_t cap)
{
	_effective_cap(_metadata, caps, CAP_SET);
	_change_cap(_metadata, CAP_EFFECTIVE, cap, CAP_SET);
}

static void __maybe_unused clear_cap(struct __test_metadata *const _metadata,
				     const cap_value_t caps)
				     const cap_value_t cap)
{
	_change_cap(_metadata, CAP_EFFECTIVE, cap, CAP_CLEAR);
}

static void __maybe_unused
set_ambient_cap(struct __test_metadata *const _metadata, const cap_value_t cap)
{
	_change_cap(_metadata, CAP_INHERITABLE, cap, CAP_SET);

	EXPECT_NE(-1, cap_set_ambient(cap, CAP_SET))
	{
		TH_LOG("Failed to set ambient capability %d: %s", cap,
		       strerror(errno));
	}
}

static void __maybe_unused clear_ambient_cap(
	struct __test_metadata *const _metadata, const cap_value_t cap)
{
	_effective_cap(_metadata, caps, CAP_CLEAR);
	EXPECT_EQ(1, cap_get_ambient(cap));
	_change_cap(_metadata, CAP_INHERITABLE, cap, CAP_CLEAR);
	EXPECT_EQ(0, cap_get_ambient(cap));
}

/* Receives an FD from a UNIX socket. Returns the received FD, or -errno. */
+8 −3
Original line number Diff line number Diff line
@@ -241,9 +241,11 @@ struct mnt_opt {
	const char *const data;
};

const struct mnt_opt mnt_tmp = {
#define MNT_TMP_DATA "size=4m,mode=700"

static const struct mnt_opt mnt_tmp = {
	.type = "tmpfs",
	.data = "size=4m,mode=700",
	.data = MNT_TMP_DATA,
};

static int mount_opt(const struct mnt_opt *const mnt, const char *const target)
@@ -4632,7 +4634,10 @@ FIXTURE_VARIANT(layout3_fs)
/* clang-format off */
FIXTURE_VARIANT_ADD(layout3_fs, tmpfs) {
	/* clang-format on */
	.mnt = mnt_tmp,
	.mnt = {
		.type = "tmpfs",
		.data = MNT_TMP_DATA,
	},
	.file_path = file1_s1d1,
};

+11 −2
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#include <string.h>
#include <sys/prctl.h>
#include <sys/socket.h>
#include <sys/syscall.h>
#include <sys/un.h>

#include "common.h"
@@ -54,6 +55,11 @@ struct service_fixture {
	};
};

static pid_t sys_gettid(void)
{
	return syscall(__NR_gettid);
}

static int set_service(struct service_fixture *const srv,
		       const struct protocol_variant prot,
		       const unsigned short index)
@@ -88,7 +94,7 @@ static int set_service(struct service_fixture *const srv,
	case AF_UNIX:
		srv->unix_addr.sun_family = prot.domain;
		sprintf(srv->unix_addr.sun_path,
			"_selftests-landlock-net-tid%d-index%d", gettid(),
			"_selftests-landlock-net-tid%d-index%d", sys_gettid(),
			index);
		srv->unix_addr_len = SUN_LEN(&srv->unix_addr);
		srv->unix_addr.sun_path[0] = '\0';
@@ -101,8 +107,11 @@ static void setup_loopback(struct __test_metadata *const _metadata)
{
	set_cap(_metadata, CAP_SYS_ADMIN);
	ASSERT_EQ(0, unshare(CLONE_NEWNET));
	ASSERT_EQ(0, system("ip link set dev lo up"));
	clear_cap(_metadata, CAP_SYS_ADMIN);

	set_ambient_cap(_metadata, CAP_NET_ADMIN);
	ASSERT_EQ(0, system("ip link set dev lo up"));
	clear_ambient_cap(_metadata, CAP_NET_ADMIN);
}

static bool is_restricted(const struct protocol_variant *const prot,