diff options
Diffstat (limited to 'comm/third_party/botan/src/cli/sandbox.cpp')
-rw-r--r-- | comm/third_party/botan/src/cli/sandbox.cpp | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/comm/third_party/botan/src/cli/sandbox.cpp b/comm/third_party/botan/src/cli/sandbox.cpp new file mode 100644 index 0000000000..6ac8007af2 --- /dev/null +++ b/comm/third_party/botan/src/cli/sandbox.cpp @@ -0,0 +1,115 @@ +/* +* (C) 2019 David Carlier <devnexen@gmail.com> +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include "sandbox.h" +#include <botan/mem_ops.h> + +#if defined(BOTAN_TARGET_OS_HAS_PLEDGE) + #include <unistd.h> +#elif defined(BOTAN_TARGET_OS_HAS_CAP_ENTER) + #include <sys/capsicum.h> + #include <unistd.h> +#elif defined(BOTAN_TARGET_OS_HAS_SETPPRIV) + #include <priv.h> +#endif + +namespace Botan_CLI { + +#if defined(BOTAN_TARGET_OS_HAS_SETPPRIV) +struct SandboxPrivDelete { + void operator()(priv_set_t *ps) + { + ::priv_emptyset(ps); + ::priv_freeset(ps); + } +}; +#endif + +Sandbox::Sandbox() + { +#if defined(BOTAN_TARGET_OS_HAS_PLEDGE) + m_name = "pledge"; +#elif defined(BOTAN_TARGET_OS_HAS_CAP_ENTER) + m_name = "capsicum"; +#elif defined(BOTAN_TARGET_OS_HAS_SETPPRIV) + m_name = "privilege"; +#else + m_name = "<none>"; +#endif + } + +bool Sandbox::init() + { + Botan::initialize_allocator(); + +#if defined(BOTAN_TARGET_OS_HAS_PLEDGE) + const static char *opts = "stdio rpath inet error"; + return (::pledge(opts, nullptr) == 0); +#elif defined(BOTAN_TARGET_OS_HAS_CAP_ENTER) + cap_rights_t wt, rd; + + if (::cap_rights_init(&wt, CAP_READ, CAP_WRITE) == nullptr) + { + return false; + } + + if (::cap_rights_init(&rd, CAP_FCNTL, CAP_EVENT, CAP_READ) == nullptr) + { + return false; + } + + if (::cap_rights_limit(STDOUT_FILENO, &wt) == -1) + { + return false; + } + + if (::cap_rights_limit(STDERR_FILENO, &wt) == -1) + { + return false; + } + + if (::cap_rights_limit(STDIN_FILENO, &rd) == -1) + { + return false; + } + + return (::cap_enter() == 0); +#elif defined(BOTAN_TARGET_OS_HAS_SETPPRIV) + priv_set_t *tmp; + std::unique_ptr<priv_set_t, SandboxPrivDelete> ps; + const char *const priv_perms[] = { + PRIV_PROC_FORK, + PRIV_PROC_EXEC, + PRIV_PROC_INFO, + PRIV_PROC_SESSION, + }; + + if ((tmp = ::priv_allocset()) == nullptr) + { + return false; + } + + ps = std::unique_ptr<priv_set_t, SandboxPrivDelete>(tmp); + ::priv_basicset(ps.get()); + + for (auto perm: priv_perms) + { + if (::priv_delset(ps.get(), perm) == -1) + { + return false; + } + } + + return true; +#else + return true; +#endif + } + +Sandbox::~Sandbox() + { + } +} |