blob: 0f3eb70051c0db3dc69357c32d8e36b7f92a8740 [file] [log] [blame] [view]
David Benjamin3e4dfbb2020-04-21 17:29:50 -04001# Using BoringSSL in a Sandbox
2
3Sandboxes are a valuable tool for securing applications, so BoringSSL aims to
4support them. However, it is difficult to make concrete API guarantees with
5sandboxes. Sandboxes remove low-level OS resources and system calls, which
6breaks platform abstractions. A syscall-filtering sandbox may, for instance, be
7sensitive to otherwise non-breaking changes to use newer syscalls
8in either BoringSSL or the C library.
9
10Some functions in BoringSSL, such as `BIO_new_file`, inherently need OS
11resources like the filesystem. We assume that sandboxed consumers either avoid
12those functions or make necessary resources available. Other functions like
13`RSA_sign` are purely computational, but still have some baseline OS
14dependencies.
15
16Sandboxes which drop privileges partway through a process's lifetime are
17additionally sensitive to OS resources retained across the transitions. For
18instance, if a library function internally opened and retained a handle to the
19user's home directory, and then the application called `chroot`, that handle
20would be a sandbox escape.
21
22This document attempts to describe these baseline OS dependencies and long-lived
23internal resources. These dependencies may change over time, but we aim to
David Benjamin90004f02023-11-30 13:10:17 -050024[work with sandboxed consumers](./BREAKING-CHANGES.md) when they do. However,
David Benjamin3e4dfbb2020-04-21 17:29:50 -040025each sandbox imposes different constraints, so, above all, sandboxed consumers
26must have ample test coverage to detect issues as they arise.
27
28## Baseline dependencies
29
30Callers must assume that any BoringSSL function may perform one of the following
31operations:
32
33### Memory allocation
34
35Any BoringSSL function may allocate memory via `malloc` and related functions.
36
37### Thread synchronization
38
39Any BoringSSL function may call into the platform's thread synchronization
40primitives, including read/write locks and the equivalent of `pthread_once`.
41These must succeed, or BoringSSL will abort the process. Callers, however, can
42assume that BoringSSL functions will not spawn internal threads, unless
43otherwise documented.
44
45Syscall-filtering sandboxes should note that BoringSSL uses `pthread_rwlock_t`
46on POSIX systems, which is less common and may not be part of other libraries'
47syscall surface. Additionally, thread synchronization primitives usually have an
48atomics-based fast path. If a sandbox blocks a necessary pthreads syscall, it
49may not show up in testing without lock contention.
50
51### Standard error
52
53Any BoringSSL function may write to `stderr` or file descriptor
54`STDERR_FILENO` (2), either via `FILE` APIs or low-level functions like `write`.
55Writes to `stderr` may fail, but there must some file at `STDERR_FILENO` which
56will tolerate error messages from BoringSSL. (The file descriptor must be
57allocated so calls to `open` do not accidentally open something else there.)
58
59Note some C standard library implementations also log to `stderr`, so callers
60should ensure this regardless.
61
62### Entropy
63
64Any BoringSSL function may draw entropy from the OS. On Windows, this uses
65`RtlGenRandom` and, on POSIX systems, this uses `getrandom`, `getentropy`, or a
66`read` from a file descriptor to `/dev/urandom`. These operations must succeed
David Benjamin7b31d692020-05-18 14:01:29 -040067or BoringSSL will abort the process. BoringSSL only probes for `getrandom`
68support once and assumes support is consistent for the lifetime of the address
69space (and any copies made via `fork`). If a syscall-filtering sandbox is
70enabled partway through this lifetime and changes whether `getrandom` works,
71BoringSSL may abort the process. Sandboxes are recommended to allow
72`getrandom`.
David Benjamin3e4dfbb2020-04-21 17:29:50 -040073
74Note even deterministic algorithms may require OS entropy. For example,
75RSASSA-PKCS1-v1_5 is deterministic, but BoringSSL draws entropy to implement
76RSA blinding.
77
78Entropy gathering additionally has some initialization dependencies described in
79the following section.
80
81## Initialization
82
83BoringSSL has some uncommon OS dependencies which are only used once to
84initialize some state. Sandboxes which drop privileges after some setup work may
85use `CRYPTO_pre_sandbox_init` to initialize this state ahead of time. Otherwise,
86callers must assume any BoringSSL function may depend on these resources, in
87addition to the operations above.
88
89### CPU capabilities
90
91On Linux ARM platforms, BoringSSL depends on OS APIs to query CPU capabilities.
9232-bit and 64-bit ARM both depend on the `getauxval` function. 32-bit ARM, to
David Benjamin74a75b32023-05-18 19:20:27 -040093work around bugs in older Android devices, may additionally read
94`/proc/cpuinfo`.
95
96On 64-bit Apple ARM platforms, BoringSSL needs to query `hw.optional.*` sysctls.
David Benjamin3e4dfbb2020-04-21 17:29:50 -040097
98If querying CPU capabilities fails, BoringSSL will still function, but may not
99perform as well.
100
101### Entropy
102
103On Linux systems without a working `getrandom`, drawing entropy from the OS
104additionally requires opening `/dev/urandom`. If this fails, BoringSSL will
105abort the process. BoringSSL retains the resulting file descriptor, even across
106privilege transitions.
107
108### Fork protection
109
110On Linux, BoringSSL allocates a page and calls `madvise` with `MADV_WIPEONFORK`
111to protect single-use state from `fork`. This operation must not crash, but if
112it fails, BoringSSL will use alternate fork-safety strategies, potentially at a
113performance cost. If it succeeds, BoringSSL assumes `MADV_WIPEONFORK` is
114functional and relies on it for fork-safety. Sandboxes must not report success
115if they ignore the `MADV_WIPEONFORK` flag. As of writing, QEMU will ignore
116`madvise` calls and report success, so BoringSSL detects this by calling
117`madvise` with -1. Sandboxes must cleanly report an error instead of crashing.
118
119Once initialized, this mechanism does not require system calls in the steady
120state, though note the configured page will be inherited across privilege
121transitions.
122
123## C and C++ standard library
124
125BoringSSL depends on the C and C++ standard libraries which, themselves, do not
126make any guarantees about sandboxes. If it produces the correct answer and has
127no observable invalid side effects, it is possible, though unreasonable, for
128`memcmp` to create and close a socket.
129
130BoringSSL assumes that functions in the C and C++ library only have the platform
131dependencies which would be "reasonable". For instance, a function in BoringSSL
132which aims not to open files will still freely call any libc memory and
133string functions.
134
135Note some C functions, such as `strerror`, may read files relating to the user's
136locale. BoringSSL may trigger these paths and assumes the sandbox environment
137will tolerate this. BoringSSL additionally cannot make guarantees about which
138system calls are used by standard library's syscall wrappers. In some cases, the
139compiler may add dependencies. (Some C++ language features emit locking code.)
140Syscall-filtering sandboxes may need updates as these dependencies change.