/* * Check decoding of landlock_add_rule syscall. * * Copyright (c) 2021 Eugene Syromyatnikov * All rights reserved. * * SPDX-License-Identifier: GPL-2.0-or-later */ #include "tests.h" #include "scno.h" #include #include #include #include #include #ifndef SKIP_IF_PROC_IS_UNAVAILABLE # define SKIP_IF_PROC_IS_UNAVAILABLE #endif #ifndef FD0_STR # define FD0_STR "" #endif #ifndef RULESET_FD # define RULESET_FD -1 #endif #ifndef RULESET_FD_STR # define RULESET_FD_STR "-1" #endif #ifndef PARENT_FD # define PARENT_FD -1 #endif #ifndef PARENT_FD_STR # define PARENT_FD_STR "-1" #endif static const char *errstr; static long sys_landlock_add_rule(int ruleset_fd, unsigned int rule_type, void *rule_attr, unsigned int flags) { static const kernel_ulong_t fill = (kernel_ulong_t) 0xd1efaced00000000ULL; kernel_ulong_t arg1 = fill | (unsigned int) ruleset_fd; kernel_ulong_t arg2 = fill | rule_type; kernel_ulong_t arg3 = (uintptr_t) rule_attr; kernel_ulong_t arg4 = fill | flags; kernel_ulong_t arg5 = fill | 0xdecaffed; kernel_ulong_t arg6 = fill | 0xdeefaced; long rc = syscall(__NR_landlock_add_rule, arg1, arg2, arg3, arg4, arg5, arg6); errstr = sprintrc(rc); return rc; } int main(void) { SKIP_IF_PROC_IS_UNAVAILABLE; TAIL_ALLOC_OBJECT_VAR_PTR(struct landlock_path_beneath_attr, attr); /* All zeroes */ sys_landlock_add_rule(0, 0, NULL, 0); printf("landlock_add_rule(0" FD0_STR ", 0 /* LANDLOCK_RULE_??? */" ", NULL, 0) = %s\n", errstr); /* Bogus values */ sys_landlock_add_rule(0xdeadc0de, 0xfacebeef, attr + 1, 1); printf("landlock_add_rule(-559038242" ", 0xfacebeef /* LANDLOCK_RULE_??? */, %p, 0x1) = %s\n", attr + 1, errstr); sys_landlock_add_rule(1729, 2, attr + 1, 0xffffffff); printf("landlock_add_rule(1729, 0x2 /* LANDLOCK_RULE_??? */, %p" ", 0xffffffff) = %s\n", attr + 1, errstr); /* Invalid pointer */ sys_landlock_add_rule(RULESET_FD, LANDLOCK_RULE_PATH_BENEATH, attr + 1, 0); printf("landlock_add_rule(" RULESET_FD_STR ", LANDLOCK_RULE_PATH_BENEATH, %p, 0) = %s\n", attr + 1, errstr); /* Short read */ sys_landlock_add_rule(RULESET_FD, LANDLOCK_RULE_PATH_BENEATH, (char *) attr + 4, 0); printf("landlock_add_rule(" RULESET_FD_STR ", LANDLOCK_RULE_PATH_BENEATH, %p, 0) = %s\n", (char *) attr + 4, errstr); /* Valid attr ptr */ static const struct { uint64_t val; const char *str; } attr_vals[] = { { ARG_STR(LANDLOCK_ACCESS_FS_EXECUTE) }, { ARG_ULL_STR(LANDLOCK_ACCESS_FS_EXECUTE|LANDLOCK_ACCESS_FS_READ_FILE|LANDLOCK_ACCESS_FS_READ_DIR|LANDLOCK_ACCESS_FS_REMOVE_FILE|LANDLOCK_ACCESS_FS_MAKE_CHAR|LANDLOCK_ACCESS_FS_MAKE_DIR|LANDLOCK_ACCESS_FS_MAKE_SOCK|LANDLOCK_ACCESS_FS_MAKE_FIFO|LANDLOCK_ACCESS_FS_MAKE_BLOCK|LANDLOCK_ACCESS_FS_MAKE_SYM|0xdebeefeddecae000) }, { ARG_ULL_STR(0xdebeefeddecae000) " /* LANDLOCK_ACCESS_FS_??? */" }, }; static const struct { int val; const char *str; } parent_fd_vals[] = { { ARG_STR(-1) }, { ARG_STR(11630) }, { PARENT_FD, PARENT_FD_STR }, }; for (size_t i = 0; i < ARRAY_SIZE(attr_vals); i++) { for (size_t j = 0; j < ARRAY_SIZE(parent_fd_vals); j++) { attr->allowed_access = attr_vals[i].val; attr->parent_fd = parent_fd_vals[j].val; sys_landlock_add_rule(RULESET_FD, LANDLOCK_RULE_PATH_BENEATH, attr, 0); printf("landlock_add_rule(" RULESET_FD_STR ", LANDLOCK_RULE_PATH_BENEATH" ", {allowed_access=%s, parent_fd=%s}, 0) = %s\n", attr_vals[i].str, parent_fd_vals[j].str, errstr); } } puts("+++ exited with 0 +++"); return 0; }