-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Prepare for FreeBSD sandboxing support #13281
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -23,6 +23,11 @@ | |
|
|
||
| #include <boost/iostreams/device/mapped_file.hpp> | ||
|
|
||
| #ifdef __FreeBSD__ | ||
| # include <sys/param.h> | ||
| # include <sys/mount.h> | ||
| #endif | ||
|
|
||
| #ifdef _WIN32 | ||
| # include <io.h> | ||
| #endif | ||
|
|
@@ -364,6 +369,13 @@ void syncParent(const Path & path) | |
| fd.fsync(); | ||
| } | ||
|
|
||
| #ifdef __FreeBSD__ | ||
| #define MOUNTEDPATHS_PARAM , std::set<Path> &mountedPaths | ||
| #define MOUNTEDPATHS_ARG , mountedPaths | ||
| #else | ||
| #define MOUNTEDPATHS_PARAM | ||
| #define MOUNTEDPATHS_ARG | ||
| #endif | ||
|
Comment on lines
+372
to
+378
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Out of curiosity: is there a reason to do this ugly define stuff rather than making it
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That would create a bunch of runtime failure modes. non-freebsd would have to assert it is not present, and freebsd would to assert it is present |
||
|
|
||
| void recursiveSync(const Path & path) | ||
| { | ||
|
|
@@ -410,11 +422,19 @@ void recursiveSync(const Path & path) | |
| } | ||
|
|
||
|
|
||
| static void _deletePath(Descriptor parentfd, const std::filesystem::path & path, uint64_t & bytesFreed) | ||
| static void _deletePath(Descriptor parentfd, const std::filesystem::path & path, uint64_t & bytesFreed MOUNTEDPATHS_PARAM) | ||
| { | ||
| #ifndef _WIN32 | ||
| checkInterrupt(); | ||
|
|
||
| #ifdef __FreeBSD__ | ||
| // In case of emergency (unmount fails for some reason) not recurse into mountpoints. | ||
| // This prevents us from tearing up the nullfs-mounted nix store. | ||
| if (mountedPaths.find(path) != mountedPaths.end()) { | ||
| return; | ||
| } | ||
| #endif | ||
|
|
||
| std::string name(baseNameOf(path.native())); | ||
|
|
||
| struct stat st; | ||
|
|
@@ -468,7 +488,7 @@ static void _deletePath(Descriptor parentfd, const std::filesystem::path & path, | |
| checkInterrupt(); | ||
| std::string childName = dirent->d_name; | ||
| if (childName == "." || childName == "..") continue; | ||
| _deletePath(dirfd(dir.get()), path + "/" + childName, bytesFreed); | ||
| _deletePath(dirfd(dir.get()), path + "/" + childName, bytesFreed MOUNTEDPATHS_ARG); | ||
| } | ||
| if (errno) throw SysError("reading directory %1%", path); | ||
| } | ||
|
|
@@ -484,7 +504,7 @@ static void _deletePath(Descriptor parentfd, const std::filesystem::path & path, | |
| #endif | ||
| } | ||
|
|
||
| static void _deletePath(const std::filesystem::path & path, uint64_t & bytesFreed) | ||
| static void _deletePath(const std::filesystem::path & path, uint64_t & bytesFreed MOUNTEDPATHS_PARAM) | ||
| { | ||
| Path dir = dirOf(path.string()); | ||
| if (dir == "") | ||
|
|
@@ -496,7 +516,7 @@ static void _deletePath(const std::filesystem::path & path, uint64_t & bytesFree | |
| throw SysError("opening directory '%1%'", path); | ||
| } | ||
|
|
||
| _deletePath(dirfd.get(), path, bytesFreed); | ||
| _deletePath(dirfd.get(), path, bytesFreed MOUNTEDPATHS_ARG); | ||
| } | ||
|
|
||
|
|
||
|
|
@@ -529,8 +549,20 @@ void createDirs(const std::filesystem::path & path) | |
| void deletePath(const std::filesystem::path & path, uint64_t & bytesFreed) | ||
| { | ||
| //Activity act(*logger, lvlDebug, "recursively deleting path '%1%'", path); | ||
| #ifdef __FreeBSD__ | ||
| std::set<Path> mountedPaths; | ||
| struct statfs *mntbuf; | ||
| int count; | ||
| if ((count = getmntinfo(&mntbuf, MNT_WAIT)) < 0) { | ||
| throw SysError("getmntinfo"); | ||
| } | ||
|
|
||
| for (int i = 0; i < count; i++) { | ||
| mountedPaths.emplace(mntbuf[i].f_mntonname); | ||
| } | ||
| #endif | ||
| bytesFreed = 0; | ||
| _deletePath(path, bytesFreed); | ||
| _deletePath(path, bytesFreed MOUNTEDPATHS_ARG); | ||
| } | ||
|
|
||
|
|
||
|
|
@@ -572,6 +604,30 @@ void AutoDelete::reset(const std::filesystem::path & p, bool recursive) { | |
|
|
||
| ////////////////////////////////////////////////////////////////////// | ||
|
|
||
| #ifdef __FreeBSD__ | ||
| AutoUnmount::AutoUnmount() : del{false} {} | ||
|
|
||
| AutoUnmount::AutoUnmount(Path &p) : path(p), del(true) {} | ||
|
|
||
| AutoUnmount::~AutoUnmount() | ||
| { | ||
| try { | ||
| if (del) { | ||
| if (unmount(path.c_str(), 0) < 0) { | ||
| throw SysError("Failed to unmount path %1%", path); | ||
| } | ||
| } | ||
| } catch (...) { | ||
| ignoreExceptionInDestructor(); | ||
| } | ||
| } | ||
|
|
||
| void AutoUnmount::cancel() | ||
| { | ||
| del = false; | ||
| } | ||
| #endif | ||
|
|
||
| ////////////////////////////////////////////////////////////////////// | ||
|
|
||
| std::string defaultTempDir() { | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| #ifdef __FreeBSD__ | ||
| # include "nix/util/freebsd-jail.hh" | ||
|
|
||
| # include <sys/resource.h> | ||
| # include <sys/param.h> | ||
| # include <sys/jail.h> | ||
| # include <sys/mount.h> | ||
|
|
||
| # include "nix/util/error.hh" | ||
| # include "nix/util/util.hh" | ||
|
|
||
| namespace nix { | ||
|
|
||
| AutoRemoveJail::AutoRemoveJail() | ||
| : del{false} | ||
| { | ||
| } | ||
|
|
||
| AutoRemoveJail::AutoRemoveJail(int jid) | ||
| : jid(jid) | ||
| , del(true) | ||
| { | ||
| } | ||
|
|
||
| AutoRemoveJail::~AutoRemoveJail() | ||
| { | ||
| try { | ||
| if (del) { | ||
| if (jail_remove(jid) < 0) { | ||
| throw SysError("Failed to remove jail %1%", jid); | ||
| } | ||
| } | ||
| } catch (...) { | ||
| ignoreExceptionInDestructor(); | ||
| } | ||
| } | ||
|
|
||
| void AutoRemoveJail::cancel() | ||
| { | ||
| del = false; | ||
| } | ||
|
|
||
| void AutoRemoveJail::reset(int j) | ||
| { | ||
| del = true; | ||
| jid = j; | ||
| } | ||
|
|
||
| ////////////////////////////////////////////////////////////////////// | ||
|
|
||
| } | ||
| #endif |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,20 @@ | ||
| #pragma once | ||
| ///@file | ||
|
|
||
| #include "nix/util/types.hh" | ||
|
|
||
| namespace nix { | ||
|
|
||
| class AutoRemoveJail | ||
| { | ||
| int jid; | ||
| bool del; | ||
| public: | ||
| AutoRemoveJail(int jid); | ||
| AutoRemoveJail(); | ||
| ~AutoRemoveJail(); | ||
| void cancel(); | ||
| void reset(int j); | ||
| }; | ||
|
|
||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| # Public headers directory | ||
|
|
||
| include_dirs += include_directories('../..') | ||
|
|
||
| headers += files( | ||
| 'freebsd-jail.hh', | ||
| ) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| sources += files( | ||
| 'freebsd-jail.cc', | ||
| ) | ||
|
|
||
| subdir('include/nix/util') |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,6 @@ | ||
| sources += files( | ||
| 'cgroup.cc', | ||
| 'namespaces.cc', | ||
| 'linux-namespaces.cc', | ||
| ) | ||
|
|
||
| subdir('include/nix/util') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missed this in review, but fixed in #13455