Repositories / jai.git
jai.git
Clone (read-only): git clone http://git.guha-anderson.com/git/jai.git
@@ -31,6 +31,18 @@ cat(path left, const path &right) return left += right; } +inline size_t +components(const path &p) +{ + return std::ranges::distance(p.begin(), p.end()); +} + +inline bool +contains(const path &dir, const path &subpath) +{ + return std::ranges::mismatch(dir, subpath).in1 == dir.end(); +} + // True is target matches pattern (with * expanded) bool glob(std::string_view pattern, std::string_view target);
@@ -487,6 +487,12 @@ Config::make_mnt_ns() for (auto d : grant_directories_) { if (d.is_relative()) d = "/" / d; + if (contains(homejaipath_, d)) + err("{}: cannot export a directory within {}", d.string(), + homejaipath_.string()); + if (contains(storagedir_, d)) + err("{}: cannot export a directory within {}", d.string(), + storagedir_.string()); xsetns(*oldns, CLONE_NEWNS); auto restore_root = asuser(); Fd src = xopenat(-1, d, O_DIRECTORY | O_PATH | O_CLOEXEC); @@ -520,12 +526,15 @@ Config::make_mnt_ns() return; restore_root.reset(); - struct stat sbold, sbnew = xfstat(*target);; - xsetns(*oldns, CLONE_NEWNS); - int staterr = stat(p.c_str(), &sbold); - xsetns(*newns, CLONE_NEWNS); - if (staterr || sbold.st_ino != sbnew.st_ino || sbold.st_dev != sbnew.st_dev) - return; + if (mode_ != kCasual) { + struct stat sbold, sbnew = xfstat(*target); + xsetns(*oldns, CLONE_NEWNS); + int staterr = stat(p.c_str(), &sbold); + xsetns(*newns, CLONE_NEWNS); + if (staterr || sbold.st_ino != sbnew.st_ino || + sbold.st_dev != sbnew.st_dev) + return; + } check_user(*target, p, true); Fd empty = xopenat(-1, kRunRoot, O_RDONLY);