aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2018-09-27 13:25:56 -0400
committerJack Lloyd <[email protected]>2018-09-27 13:25:56 -0400
commit9d94c3f3e0cf9f1234497593516bc2776cc89a0b (patch)
treeabc2c7850a07b173a657fd561661fd65fd090e08 /src/lib
parent62946a6d82df33fd7c78104f9151a2b6cdc8599e (diff)
Add OS::running_in_privileged_state
Avoid any getenv toggles or reading /proc if we are setuid/setgid. It is possible there is or will someday be some file in /proc that is world-readable, but if read by a privileged user causes some side effect.
Diffstat (limited to 'src/lib')
-rw-r--r--src/lib/entropy/entropy_srcs.cpp3
-rw-r--r--src/lib/ffi/ffi.cpp3
-rw-r--r--src/lib/utils/os_utils.cpp46
-rw-r--r--src/lib/utils/os_utils.h6
4 files changed, 41 insertions, 17 deletions
diff --git a/src/lib/entropy/entropy_srcs.cpp b/src/lib/entropy/entropy_srcs.cpp
index 9141db366..85e0b6dc5 100644
--- a/src/lib/entropy/entropy_srcs.cpp
+++ b/src/lib/entropy/entropy_srcs.cpp
@@ -30,6 +30,7 @@
#if defined(BOTAN_HAS_ENTROPY_SRC_PROC_WALKER)
#include <botan/internal/proc_walk.h>
+ #include <botan/internal/os_utils.h>
#endif
#if defined(BOTAN_HAS_ENTROPY_SRC_GETENTROPY)
@@ -97,7 +98,7 @@ std::unique_ptr<Entropy_Source> Entropy_Source::create(const std::string& name)
#endif
#if defined(BOTAN_HAS_ENTROPY_SRC_PROC_WALKER)
- if(name == "proc_walk")
+ if(name == "proc_walk" && OS::running_in_privileged_state() == false)
{
const std::string root_dir = BOTAN_ENTROPY_PROC_FS_PATH;
if(!root_dir.empty())
diff --git a/src/lib/ffi/ffi.cpp b/src/lib/ffi/ffi.cpp
index 162d96438..65c8dbcb4 100644
--- a/src/lib/ffi/ffi.cpp
+++ b/src/lib/ffi/ffi.cpp
@@ -6,6 +6,7 @@
#include <botan/ffi.h>
#include <botan/internal/ffi_util.h>
+#include <botan/internal/os_utils.h>
#include <botan/version.h>
#include <botan/mem_ops.h>
#include <botan/hex.h>
@@ -17,7 +18,7 @@ namespace Botan_FFI {
int ffi_error_exception_thrown(const char* func_name, const char* exn, int rc)
{
- if(std::getenv("BOTAN_FFI_PRINT_EXCEPTIONS"))
+ if(Botan::OS::running_in_privileged_state() == false && std::getenv("BOTAN_FFI_PRINT_EXCEPTIONS") != nullptr)
{
std::fprintf(stderr, "in %s exception '%s' returning %d\n", func_name, exn, rc);
}
diff --git a/src/lib/utils/os_utils.cpp b/src/lib/utils/os_utils.cpp
index c7f04a855..01356f64d 100644
--- a/src/lib/utils/os_utils.cpp
+++ b/src/lib/utils/os_utils.cpp
@@ -26,7 +26,13 @@
#include <setjmp.h>
#include <unistd.h>
#include <errno.h>
-#elif defined(BOTAN_TARGET_OS_HAS_WIN32)
+#endif
+
+#if defined(BOTAN_TARGET_OS_HAS_GETAUXVAL)
+ #include <sys/auxv.h>
+#endif
+
+#if defined(BOTAN_TARGET_OS_HAS_WIN32)
#define NOMINMAX 1
#include <windows.h>
#endif
@@ -74,6 +80,17 @@ uint32_t OS::get_process_id()
#endif
}
+bool OS::running_in_privileged_state()
+ {
+#if defined(BOTAN_TARGET_OS_HAS_GETAUXVAL) && defined(AT_SECURE)
+ return ::getauxval(AT_SECURE) != 0;
+#elif defined(BOTAN_TARGET_OS_HAS_POSIX1)
+ return (::getuid() != ::geteuid()) || (::getgid() != ::getegid());
+#else
+ return false;
+#endif
+ }
+
uint64_t OS::get_processor_timestamp()
{
uint64_t rtc = 0;
@@ -217,8 +234,11 @@ size_t OS::system_page_size()
size_t OS::get_memory_locking_limit()
{
-#if defined(BOTAN_TARGET_OS_HAS_POSIX1)
+#if defined(BOTAN_TARGET_OS_HAS_POSIX1) && defined(RLIMIT_MEMLOCK)
/*
+ * If RLIMIT_MEMLOCK is not defined, likely the OS does not support
+ * unprivileged mlock calls.
+ *
* Linux defaults to only 64 KiB of mlockable memory per process
* (too small) but BSDs offer a small fraction of total RAM (more
* than we need). Bound the total mlock size to 512 KiB which is
@@ -232,17 +252,19 @@ size_t OS::get_memory_locking_limit()
/*
* Allow override via env variable
*/
- if(const char* env = std::getenv("BOTAN_MLOCK_POOL_SIZE"))
+ if(OS::running_in_privileged_state() == false)
{
- try
+ if(const char* env = std::getenv("BOTAN_MLOCK_POOL_SIZE"))
{
- const size_t user_req = std::stoul(env, nullptr);
- mlock_requested = std::min(user_req, mlock_requested);
+ try
+ {
+ const size_t user_req = std::stoul(env, nullptr);
+ mlock_requested = std::min(user_req, mlock_requested);
+ }
+ catch(std::exception&) { /* ignore it */ }
}
- catch(std::exception&) { /* ignore it */ }
}
-#if defined(RLIMIT_MEMLOCK)
if(mlock_requested > 0)
{
struct ::rlimit limits;
@@ -258,13 +280,6 @@ size_t OS::get_memory_locking_limit()
return std::min<size_t>(limits.rlim_cur, mlock_requested * 1024);
}
-#else
- /*
- * If RLIMIT_MEMLOCK is not defined, likely the OS does not support
- * unprivileged mlock calls.
- */
- return 0;
-#endif
#elif defined(BOTAN_TARGET_OS_HAS_VIRTUAL_LOCK)
SIZE_T working_min = 0, working_max = 0;
@@ -294,6 +309,7 @@ size_t OS::get_memory_locking_limit()
}
#endif
+ // Not supported on this platform
return 0;
}
diff --git a/src/lib/utils/os_utils.h b/src/lib/utils/os_utils.h
index 5210b2523..778ace4e9 100644
--- a/src/lib/utils/os_utils.h
+++ b/src/lib/utils/os_utils.h
@@ -32,6 +32,12 @@ namespace OS {
uint32_t BOTAN_TEST_API get_process_id();
/**
+* Test if we are currently running with elevated permissions
+* eg setuid, setgid, or with POSIX caps set.
+*/
+bool running_in_privileged_state();
+
+/**
* @return CPU processor clock, if available
*
* On Windows, calls QueryPerformanceCounter.