Path: blob/main/tests/sys/kern/jail_lookup_root.c
105687 views
/*-1* SPDX-License-Identifier: BSD-2-Clause2*3* Copyright (c) 2025 Mark Johnston <[email protected]>4*/56#include <sys/param.h>7#include <sys/jail.h>8#include <sys/mount.h>9#include <sys/stat.h>1011#include <err.h>12#include <errno.h>13#include <fcntl.h>14#include <jail.h>15#include <mntopts.h>16#include <stdio.h>17#include <stdlib.h>1819#include <atf-c.h>2021static void22mkdir_checked(const char *dir, mode_t mode)23{24int error;2526error = mkdir(dir, mode);27ATF_REQUIRE_MSG(error == 0 || errno == EEXIST,28"mkdir %s: %s", dir, strerror(errno));29}3031static void __unused32mount_nullfs(const char *dir, const char *target)33{34struct iovec *iov;35char errmsg[1024];36int error, iovlen;3738iov = NULL;39iovlen = 0;4041build_iovec(&iov, &iovlen, __DECONST(char *, "fstype"),42__DECONST(char *, "nullfs"), (size_t)-1);43build_iovec(&iov, &iovlen, __DECONST(char *, "fspath"),44__DECONST(char *, target), (size_t)-1);45build_iovec(&iov, &iovlen, __DECONST(char *, "from"),46__DECONST(char *, dir), (size_t)-1);47build_iovec(&iov, &iovlen, __DECONST(char *, "errmsg"),48errmsg, sizeof(errmsg));4950errmsg[0] = '\0';51error = nmount(iov, iovlen, 0);52ATF_REQUIRE_MSG(error == 0, "nmount: %s",53errmsg[0] != '\0' ? errmsg : strerror(errno));5455free_iovec(&iov, &iovlen);56}5758ATF_TC_WITH_CLEANUP(jail_root);59ATF_TC_HEAD(jail_root, tc)60{61atf_tc_set_md_var(tc, "require.user", "root");62}63ATF_TC_BODY(jail_root, tc)64{65int error, fd, jid;6667mkdir_checked("./root", 0755);68mkdir_checked("./root/a", 0755);69mkdir_checked("./root/b", 0755);70mkdir_checked("./root/a/c", 0755);7172jid = jail_setv(JAIL_CREATE | JAIL_ATTACH,73"name", "nullfs_jail_root_test",74"allow.mount", "true",75"allow.mount.nullfs", "true",76"enforce_statfs", "1",77"path", "./root",78"persist", NULL,79NULL);80ATF_REQUIRE_MSG(jid >= 0, "jail_setv: %s", jail_errmsg);8182mount_nullfs("/a", "/b");8384error = chdir("/b/c");85ATF_REQUIRE(error == 0);8687error = rename("/a/c", "/c");88ATF_REQUIRE(error == 0);8990/* Descending to the jail root should be ok. */91error = chdir("..");92ATF_REQUIRE(error == 0);9394/* Going beyond the root will trigger an error. */95error = chdir("..");96ATF_REQUIRE_ERRNO(ENOENT, error != 0);97fd = open("..", O_RDONLY | O_DIRECTORY);98ATF_REQUIRE_ERRNO(ENOENT, fd < 0);99}100ATF_TC_CLEANUP(jail_root, tc)101{102struct statfs fs;103fsid_t fsid;104int error, jid;105106error = statfs("./root/b", &fs);107if (error != 0)108err(1, "statfs ./b");109fsid = fs.f_fsid;110error = statfs("./root", &fs);111if (error != 0)112err(1, "statfs ./root");113if (fsid.val[0] != fs.f_fsid.val[0] ||114fsid.val[1] != fs.f_fsid.val[1]) {115error = unmount("./root/b", 0);116if (error != 0)117err(1, "unmount ./root/b");118}119120jid = jail_getid("nullfs_jail_root_test");121if (jid >= 0) {122error = jail_remove(jid);123if (error != 0)124err(1, "jail_remove");125}126}127128ATF_TP_ADD_TCS(tp)129{130ATF_TP_ADD_TC(tp, jail_root);131return (atf_no_error());132}133134135