Botan 3.6.0
Crypto and TLS for C&
os_utils.h
Go to the documentation of this file.
1/*
2* OS specific utility functions
3* (C) 2015,2016,2017,2018 Jack Lloyd
4*
5* Botan is released under the Simplified BSD License (see license.txt)
6*/
7
8#ifndef BOTAN_OS_UTILS_H_
9#define BOTAN_OS_UTILS_H_
10
11#include <botan/types.h>
12#include <functional>
13#include <string>
14#include <vector>
15
16#if defined(BOTAN_TARGET_OS_HAS_THREADS)
17 #include <thread>
18#endif
19
20namespace Botan::OS {
21
22/*
23* This header is internal (not installed) and these functions are not
24* intended to be called by applications. However they are given public
25* visibility (using BOTAN_TEST_API macro) for the tests. This also probably
26* allows them to be overridden by the application on ELF systems, but
27* this hasn't been tested.
28*/
29
30/**
31* @return process ID assigned by the operating system.
32*
33* On Unix and Windows systems, this always returns a result
34*
35* On systems where there is no processes to speak of (for example on baremetal
36* systems or within a unikernel), this function returns zero.
37*/
39
40/**
41* Test if we are currently running with elevated permissions
42* eg setuid, setgid, or with POSIX caps set.
43*/
45
46/**
47* @return CPU processor clock, if available
48*
49* On Windows, calls QueryPerformanceCounter.
50*
51* Under GCC or Clang on supported platforms the hardware cycle counter is queried.
52* Currently supported processors are x86, PPC, Alpha, SPARC, IA-64, S/390x, and HP-PA.
53* If no CPU cycle counter is available on this system, returns zero.
54*/
56
58
59/**
60* Return true if get_auxval is implemented on this system
61*/
62bool has_auxval();
63
64/**
65* If get_auxval is supported, returns the relevant value for AT_HWCAP
66*
67* If get_auxval is not supported on this system, arbitrarily returns 0
68*/
69unsigned long auxval_hwcap();
70
71/**
72* If get_auxval is supported, returns the relevant value for AT_HWCAP2
73*
74* If get_auxval is not supported on this system, arbitrarily returns 0
75*/
76unsigned long auxval_hwcap2();
77
78/**
79* Return the ELF auxiliary vector cooresponding to the given ID.
80* This only makes sense on Unix-like systems and is currently
81* only supported on Linux, Android, and FreeBSD.
82*
83* Returns zero if not supported on the current system or if
84* the id provided is not known.
85*/
86unsigned long get_auxval(unsigned long id);
87
88/*
89* @return best resolution timestamp available
90*
91* The epoch and update rate of this clock is arbitrary and depending
92* on the hardware it may not tick at a constant rate.
93*
94* Uses hardware cycle counter, if available.
95* On POSIX platforms clock_gettime is used with a monotonic timer
96* As a final fallback std::chrono::high_resolution_clock is used.
97*/
99
100/**
101* @return system clock (reflecting wall clock) with best resolution
102* available, normalized to nanoseconds resolution.
103*/
105
106/**
107* Format a time
108*
109* Converts the time_t to a local time representation,
110* then invokes std::put_time with the specified format.
111*/
112std::string BOTAN_TEST_API format_time(time_t time, const std::string& format);
113
114/**
115* @return maximum amount of memory (in bytes) Botan could/should
116* hyptothetically allocate for the memory poool. Reads environment
117* variable "BOTAN_MLOCK_POOL_SIZE", set to "0" to disable pool.
118*/
120
121/**
122* Return the size of a memory page, if that can be derived on the
123* current system. Otherwise returns some default value (eg 4096)
124*/
125size_t system_page_size();
126
127/**
128* Read the value of an environment variable, setting it to value_out if it
129* exists. Returns false and sets value_out to empty string if no such variable
130* is set. If the process seems to be running in a privileged state (such as
131* setuid) then always returns false and does not examine the environment.
132*/
133bool read_env_variable(std::string& value_out, std::string_view var_name);
134
135/**
136* Read the value of an environment variable and convert it to an
137* integer. If not set or conversion fails, returns the default value.
138*
139* If the process seems to be running in a privileged state (such as setuid)
140* then always returns nullptr, similiar to glibc's secure_getenv.
141*/
142size_t read_env_variable_sz(std::string_view var_name, size_t def_value = 0);
143
144/**
145* Request count pages of RAM which are locked into memory using mlock,
146* VirtualLock, or some similar OS specific API. Free it with free_locked_pages.
147*
148* Returns an empty list on failure. This function is allowed to return fewer
149* than count pages.
150*
151* The contents of the allocated pages are undefined.
152*
153* Each page is preceded by and followed by a page which is marked
154* as noaccess, such that accessing it will cause a crash. This turns
155* out of bound reads/writes into crash events.
156*
157* @param count requested number of locked pages
158*/
159std::vector<void*> allocate_locked_pages(size_t count);
160
161/**
162* Free memory allocated by allocate_locked_pages
163* @param pages a list of pages returned by allocate_locked_pages
164*/
165void free_locked_pages(const std::vector<void*>& pages);
166
167/**
168* Set the MMU to prohibit access to this page
169*/
170void page_prohibit_access(void* page);
171
172/**
173* Set the MMU to allow R/W access to this page
174*/
175void page_allow_access(void* page);
176
177/**
178* Set a ID to a page's range expressed by size bytes
179*/
180void page_named(void* page, size_t size);
181
182#if defined(BOTAN_TARGET_OS_HAS_THREADS)
183void set_thread_name(std::thread& thread, const std::string& name);
184#endif
185
186/**
187* Run a probe instruction to test for support for a CPU instruction.
188* Runs in system-specific env that catches illegal instructions; this
189* function always fails if the OS doesn't provide this.
190* Returns value of probe_fn, if it could run.
191* If error occurs, returns negative number.
192* This allows probe_fn to indicate errors of its own, if it wants.
193* For example the instruction might not only be only available on some
194* CPUs, but also buggy on some subset of these - the probe function
195* can test to make sure the instruction works properly before
196* indicating that the instruction is available.
197*
198* @warning on Unix systems uses signal handling in a way that is not
199* thread safe. It should only be called in a single-threaded context
200* (ie, at static init time).
201*
202* If probe_fn throws an exception the result is undefined.
203*
204* Return codes:
205* -1 illegal instruction detected
206*/
207int BOTAN_TEST_API run_cpu_instruction_probe(const std::function<int()>& probe_fn);
208
209/**
210* Represents a terminal state
211*/
213 public:
214 /**
215 * Reenable echo on this terminal. Can be safely called
216 * multiple times. May throw if an error occurs.
217 */
218 virtual void reenable_echo() = 0;
219
220 /**
221 * Implicitly calls reenable_echo, but swallows/ignored all
222 * errors which would leave the terminal in an invalid state.
223 */
224 virtual ~Echo_Suppression() = default;
225};
226
227/**
228* Suppress echo on the terminal
229* Returns null if this operation is not supported on the current system.
230*/
231std::unique_ptr<Echo_Suppression> BOTAN_UNSTABLE_API suppress_echo_on_terminal();
232
233} // namespace Botan::OS
234
235#endif
virtual void reenable_echo()=0
virtual ~Echo_Suppression()=default
std::string name
#define BOTAN_UNSTABLE_API
Definition compiler.h:44
#define BOTAN_TEST_API
Definition compiler.h:51
bool running_in_privileged_state()
Definition os_utils.cpp:176
size_t get_memory_locking_limit()
Definition os_utils.cpp:381
uint64_t BOTAN_TEST_API get_high_resolution_clock()
Definition os_utils.cpp:279
size_t BOTAN_TEST_API get_cpu_available()
Definition os_utils.cpp:247
std::unique_ptr< Echo_Suppression > BOTAN_UNSTABLE_API suppress_echo_on_terminal()
Definition os_utils.cpp:756
size_t read_env_variable_sz(std::string_view var_name, size_t def_value=0)
Definition os_utils.cpp:475
void page_allow_access(void *page)
Definition os_utils.cpp:606
unsigned long auxval_hwcap()
Definition os_utils.cpp:136
bool has_auxval()
Definition os_utils.cpp:124
std::string BOTAN_TEST_API format_time(time_t time, const std::string &format)
Definition os_utils.cpp:341
bool read_env_variable(std::string &value_out, std::string_view var_name)
Definition os_utils.cpp:442
void page_prohibit_access(void *page)
Definition os_utils.cpp:620
int BOTAN_TEST_API run_cpu_instruction_probe(const std::function< int()> &probe_fn)
Definition os_utils.cpp:716
std::vector< void * > allocate_locked_pages(size_t count)
Definition os_utils.cpp:515
size_t system_page_size()
Definition os_utils.cpp:361
uint64_t BOTAN_TEST_API get_system_timestamp_ns()
Definition os_utils.cpp:329
unsigned long get_auxval(unsigned long id)
Definition os_utils.cpp:156
void free_locked_pages(const std::vector< void * > &pages)
Definition os_utils.cpp:634
void page_named(void *page, size_t size)
Definition os_utils.cpp:656
uint32_t BOTAN_TEST_API get_process_id()
Definition os_utils.cpp:112
uint64_t BOTAN_TEST_API get_cpu_cycle_counter()
Definition os_utils.cpp:190
unsigned long auxval_hwcap2()
Definition os_utils.cpp:146