Unverified Commit 76b902f8 authored by Mickaël Salaün's avatar Mickaël Salaün
Browse files

samples/landlock: Add support for file reparenting



Add LANDLOCK_ACCESS_FS_REFER to the "roughly write" access rights and
leverage the Landlock ABI version to only try to enforce it if it is
supported by the running kernel.

Reviewed-by: default avatarPaul Moore <paul@paul-moore.com>
Signed-off-by: default avatarMickaël Salaün <mic@digikod.net>
Link: https://lore.kernel.org/r/20220506161102.525323-10-mic@digikod.net
parent f4056b92
Loading
Loading
Loading
Loading
+27 −13
Original line number Diff line number Diff line
@@ -159,7 +159,11 @@ static int populate_ruleset(const char *const env_var, const int ruleset_fd,
	LANDLOCK_ACCESS_FS_MAKE_SOCK | \
	LANDLOCK_ACCESS_FS_MAKE_FIFO | \
	LANDLOCK_ACCESS_FS_MAKE_BLOCK | \
	LANDLOCK_ACCESS_FS_MAKE_SYM)
	LANDLOCK_ACCESS_FS_MAKE_SYM | \
	LANDLOCK_ACCESS_FS_REFER)

#define ACCESS_ABI_2 ( \
	LANDLOCK_ACCESS_FS_REFER)

/* clang-format on */

@@ -167,10 +171,11 @@ int main(const int argc, char *const argv[], char *const *const envp)
{
	const char *cmd_path;
	char *const *cmd_argv;
	int ruleset_fd;
	int ruleset_fd, abi;
	__u64 access_fs_ro = ACCESS_FS_ROUGHLY_READ,
	      access_fs_rw = ACCESS_FS_ROUGHLY_READ | ACCESS_FS_ROUGHLY_WRITE;
	struct landlock_ruleset_attr ruleset_attr = {
		.handled_access_fs = ACCESS_FS_ROUGHLY_READ |
				     ACCESS_FS_ROUGHLY_WRITE,
		.handled_access_fs = access_fs_rw,
	};

	if (argc < 2) {
@@ -196,12 +201,11 @@ int main(const int argc, char *const argv[], char *const *const envp)
		return 1;
	}

	ruleset_fd =
		landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
	if (ruleset_fd < 0) {
	abi = landlock_create_ruleset(NULL, 0, LANDLOCK_CREATE_RULESET_VERSION);
	if (abi < 0) {
		const int err = errno;

		perror("Failed to create a ruleset");
		perror("Failed to check Landlock compatibility");
		switch (err) {
		case ENOSYS:
			fprintf(stderr,
@@ -221,13 +225,23 @@ int main(const int argc, char *const argv[], char *const *const envp)
		}
		return 1;
	}
	if (populate_ruleset(ENV_FS_RO_NAME, ruleset_fd,
			     ACCESS_FS_ROUGHLY_READ)) {
	/* Best-effort security. */
	if (abi < 2) {
		ruleset_attr.handled_access_fs &= ~ACCESS_ABI_2;
		access_fs_ro &= ~ACCESS_ABI_2;
		access_fs_rw &= ~ACCESS_ABI_2;
	}

	ruleset_fd =
		landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
	if (ruleset_fd < 0) {
		perror("Failed to create a ruleset");
		return 1;
	}
	if (populate_ruleset(ENV_FS_RO_NAME, ruleset_fd, access_fs_ro)) {
		goto err_close_ruleset;
	}
	if (populate_ruleset(ENV_FS_RW_NAME, ruleset_fd,
			     ACCESS_FS_ROUGHLY_READ |
				     ACCESS_FS_ROUGHLY_WRITE)) {
	if (populate_ruleset(ENV_FS_RW_NAME, ruleset_fd, access_fs_rw)) {
		goto err_close_ruleset;
	}
	if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {