Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions crypto/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -504,7 +504,7 @@ add_library(
trust_token/trust_token.c
trust_token/voprf.c
ube/ube.c
ube/fork_detect.c
ube/fork_ube_detect.c
ube/vm_ube_detect.c
x509/a_digest.c
x509/a_sign.c
Expand Down Expand Up @@ -875,7 +875,7 @@ if(BUILD_TESTING)
thread_test.cc
trust_token/trust_token_test.cc
ube/ube_test.cc
ube/fork_detect_test.cc
ube/fork_ube_detect_test.cc
ube/vm_ube_detect_test.cc
x509/tab_test.cc
x509/x509_test.cc
Expand Down
8 changes: 4 additions & 4 deletions crypto/fipsmodule/rand/rand_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ TEST_F(randTest, UbeDetectionMocked) {

MockedUbeDetection(
[](uint64_t gn) {
set_fork_generation_number_FOR_TESTING(gn);
set_fork_ube_generation_number_FOR_TESTING(gn);
}
);

Expand All @@ -245,7 +245,7 @@ TEST_F(randTest, UbeDetectionMocked) {
TEST_F(randTest, NotObviouslyBroken) {
static const uint8_t kZeros[256] = {0};

maybeDisableSomeForkDetectMechanisms();
maybeDisableSomeForkUbeDetectMechanisms();

uint8_t buf1[256], buf2[256];
RAND_bytes(buf1, sizeof(buf1));
Expand Down Expand Up @@ -330,7 +330,7 @@ static bool ForkAndRand(bssl::Span<uint8_t> out) {
TEST_F(randTest, Fork) {
static const uint8_t kZeros[16] = {0};

maybeDisableSomeForkDetectMechanisms();
maybeDisableSomeForkUbeDetectMechanisms();

// Draw a little entropy to initialize any internal PRNG buffering.
uint8_t byte;
Expand Down Expand Up @@ -393,7 +393,7 @@ TEST_F(randTest, Threads) {
constexpr size_t kFewerThreads = 10;
constexpr size_t kMoreThreads = 20;

maybeDisableSomeForkDetectMechanisms();
maybeDisableSomeForkUbeDetectMechanisms();

// Draw entropy in parallel.
RunConcurrentRands(kFewerThreads);
Expand Down
4 changes: 2 additions & 2 deletions crypto/fipsmodule/rsa/rsa_impl.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@
#include "../bn/internal.h"
#include "../../internal.h"
#include "../delocate.h"
#include "../../ube/fork_detect.h"
#include "../../ube/fork_ube_detect.h"

static int ensure_fixed_copy(BIGNUM **out, const BIGNUM *in, int width) {
if (*out != NULL) {
Expand Down Expand Up @@ -252,7 +252,7 @@ static BN_BLINDING *rsa_blinding_get(RSA *rsa, size_t *index_used,
assert(rsa->mont_n != NULL);

BN_BLINDING *ret = NULL;
const uint64_t fork_generation = CRYPTO_get_fork_generation();
const uint64_t fork_generation = CRYPTO_get_fork_ube_generation();
CRYPTO_MUTEX_lock_write(&rsa->lock);

// Wipe the blinding cache on |fork|.
Expand Down
4 changes: 2 additions & 2 deletions crypto/rand_extra/urandom_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
#include <sys/syscall.h>
#include <sys/user.h>

#include "../ube/fork_detect.h"
#include "../ube/fork_ube_detect.h"
#include "getrandom_fillin.h"

#include "../test/test_util.h"
Expand Down Expand Up @@ -631,7 +631,7 @@ TEST(URandomTest, Test) {
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);

maybeDisableSomeForkDetectMechanisms();
maybeDisableSomeForkUbeDetectMechanisms();

return RUN_ALL_TESTS();
}
Expand Down
6 changes: 3 additions & 3 deletions crypto/test/test_util.cc
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
#include <openssl/err.h>

#include "../internal.h"
#include "../ube/fork_detect.h"
#include "../ube/fork_ube_detect.h"
#include "openssl/pem.h"
#include "openssl/rand.h"

Expand Down Expand Up @@ -370,8 +370,8 @@ bool forkAndRunTest(std::function<bool()> child_func,
#endif
}

void maybeDisableSomeForkDetectMechanisms(void) {
if (getenv("BORINGSSL_IGNORE_FORK_DETECTION")) {
void maybeDisableSomeForkUbeDetectMechanisms(void) {
if (getenv("AWSLC_IGNORE_FORK_UBE_DETECTION")) {
CRYPTO_fork_detect_ignore_wipeonfork_FOR_TESTING();
CRYPTO_fork_detect_ignore_inheritzero_FOR_TESTING();
}
Expand Down
2 changes: 1 addition & 1 deletion crypto/test/test_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ bool threadTest(const size_t numberOfThreads,
bool forkAndRunTest(std::function<bool()> child_func,
std::function<bool()> parent_func);

void maybeDisableSomeForkDetectMechanisms(void);
void maybeDisableSomeForkUbeDetectMechanisms(void);
bool runtimeEmulationIsIntelSde(void);
bool addressSanitizerIsEnabled(void);

Expand Down
48 changes: 24 additions & 24 deletions crypto/ube/fork_detect.c → crypto/ube/fork_ube_detect.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@
// can't do anything. In this case randomness generation falls back to
// randomizing the state per-request.
#if defined(OPENSSL_LINUX)
#define AWSLC_FORK_DETECTION_SUPPORTED
#define AWSLC_FORK_UBE_DETECTION_SUPPORTED
#if !defined(_GNU_SOURCE)
#define _GNU_SOURCE // Needed for madvise() and MAP_ANONYMOUS.
#endif
#elif defined(OPENSSL_FREEBSD) || defined(OPENSSL_OPENBSD) || defined(OPENSSL_NETBSD)
#define AWSLC_FORK_DETECTION_SUPPORTED
#define AWSLC_FORK_UBE_DETECTION_SUPPORTED
// FreeBSD requires POSIX compatibility off for its syscalls
// (enables __BSD_VISIBLE). Without the below line, <sys/mman.h> cannot be
// imported (it requires __BSD_VISIBLE).
Expand All @@ -40,14 +40,14 @@
#define AWSLC_PLATFORM_DOES_NOT_FORK
#endif

#include "fork_detect.h"
#include "fork_ube_detect.h"
#include "../internal.h"

static struct CRYPTO_STATIC_MUTEX ignore_testing_lock = CRYPTO_STATIC_MUTEX_INIT;
static int ignore_wipeonfork = 0;
static int ignore_inheritzero = 0;

#if defined(AWSLC_FORK_DETECTION_SUPPORTED)
#if defined(AWSLC_FORK_UBE_DETECTION_SUPPORTED)

#include <openssl/base.h>
#include <openssl/type_check.h>
Expand All @@ -56,16 +56,16 @@ static int ignore_inheritzero = 0;

#include <stdlib.h>

static CRYPTO_once_t fork_detect_once = CRYPTO_ONCE_INIT;
static struct CRYPTO_STATIC_MUTEX fork_detect_lock = CRYPTO_STATIC_MUTEX_INIT;
static CRYPTO_once_t fork_detect_ube_once = CRYPTO_ONCE_INIT;
static struct CRYPTO_STATIC_MUTEX fork_detect_ube_lock = CRYPTO_STATIC_MUTEX_INIT;

// This value (pointed to) is |volatile| because the value pointed to may be
// changed by external forces (i.e. the kernel wiping the page) thus the
// compiler must not assume that it has exclusive access to it.
static volatile char *fork_detect_addr = NULL;
static uint64_t fork_generation = 0;
static uint64_t fgn = 0;

static int ignore_all_fork_detection(void) {
static int ignore_all_fork_ube_detection(void) {

CRYPTO_STATIC_MUTEX_lock_read(&ignore_testing_lock);
if (ignore_wipeonfork == 1 &&
Expand Down Expand Up @@ -184,7 +184,7 @@ static void init_fork_detect(void) {
void *addr = MAP_FAILED;
long page_size = 0;

if (ignore_all_fork_detection() == 1) {
if (ignore_all_fork_ube_detection() == 1) {
return;
}

Expand Down Expand Up @@ -216,10 +216,10 @@ static void init_fork_detect(void) {

*((volatile char *) addr) = 1;
fork_detect_addr = addr;
fork_generation = 1;
fgn = 1;
}

uint64_t CRYPTO_get_fork_generation(void) {
uint64_t CRYPTO_get_fork_ube_generation(void) {
// In a single-threaded process, there are obviously no races because there's
// only a single mutator in the address space.
//
Expand All @@ -234,39 +234,39 @@ uint64_t CRYPTO_get_fork_generation(void) {
//
// One cannot convert this to thread-local values to avoid locking. See e.g.
// https://github.com/aws/s2n-tls/issues/3107.
CRYPTO_once(&fork_detect_once, init_fork_detect);
CRYPTO_once(&fork_detect_ube_once, init_fork_detect);

volatile char *const flag_ptr = fork_detect_addr;
if (flag_ptr == NULL) {
// Our kernel does not support fork detection.
return 0;
}

struct CRYPTO_STATIC_MUTEX *const lock = &fork_detect_lock;
struct CRYPTO_STATIC_MUTEX *const lock = &fork_detect_ube_lock;

CRYPTO_STATIC_MUTEX_lock_read(lock);
uint64_t current_generation = fork_generation;
uint64_t current_fgn = fgn;
if (*flag_ptr) {
CRYPTO_STATIC_MUTEX_unlock_read(lock);
return current_generation;
return current_fgn;
}

CRYPTO_STATIC_MUTEX_unlock_read(lock);
CRYPTO_STATIC_MUTEX_lock_write(lock);
current_generation = fork_generation;
current_fgn = fgn;
if (*flag_ptr == 0) {
// A fork has occurred.
*flag_ptr = 1;

current_generation++;
if (current_generation == 0) {
current_generation = 1;
current_fgn++;
if (current_fgn == 0) {
current_fgn = 1;
}
fork_generation = current_generation;
fgn = current_fgn;
}
CRYPTO_STATIC_MUTEX_unlock_write(lock);

return current_generation;
return current_fgn;
}

#elif defined(AWSLC_PLATFORM_DOES_NOT_FORK)
Expand All @@ -275,17 +275,17 @@ uint64_t CRYPTO_get_fork_generation(void) {
// fork detection support. Returning a constant non zero value makes BoringSSL
// assume address space duplication is not a concern and adding entropy to
// every RAND_bytes call is not needed.
uint64_t CRYPTO_get_fork_generation(void) { return 0xc0ffee; }
uint64_t CRYPTO_get_fork_ube_generation(void) { return 0xc0ffee; }

#else

// These platforms may fork, but we do not have a mitigation mechanism in
// place. Returning a constant zero value makes BoringSSL assume that address
// space duplication could have occured on any call entropy must be added to
// every RAND_bytes call.
uint64_t CRYPTO_get_fork_generation(void) { return 0; }
uint64_t CRYPTO_get_fork_ube_generation(void) { return 0; }

#endif // defined(AWSLC_FORK_DETECTION_SUPPORTED)
#endif // defined(AWSLC_FORK_UBE_DETECTION_SUPPORTED)

void CRYPTO_fork_detect_ignore_wipeonfork_FOR_TESTING(void) {
CRYPTO_STATIC_MUTEX_lock_write(&ignore_testing_lock);
Expand Down
18 changes: 9 additions & 9 deletions crypto/ube/fork_detect.h → crypto/ube/fork_ube_detect.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
* OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */

#ifndef OPENSSL_HEADER_CRYPTO_FORK_DETECT_H
#define OPENSSL_HEADER_CRYPTO_FORK_DETECT_H
#ifndef OPENSSL_HEADER_CRYPTO_FORK_UBE_DETECT_H
#define OPENSSL_HEADER_CRYPTO_FORK_UBE_DETECT_H

#include <openssl/base.h>

Expand All @@ -24,11 +24,11 @@ extern "C" {
#endif


// crypto_get_fork_generation returns the fork generation number for the current
// process, or zero if not supported on the platform. The fork generation number
// is a non-zero, strictly-monotonic counter with the property that, if queried
// in an address space and then again in a subsequently forked copy, the forked
// address space will observe a greater value.
// CRYPTO_get_fork_ube_generation returns the fork generation number for the
// current process, or zero if not supported on the platform. The fork
// generation number is a non-zero, strictly-monotonic counter with the property
// that, if queried in an address space and then again in a subsequently forked
// copy, the forked address space will observe a greater value.
//
// This function may be used to clear cached values across a fork. When
// initializing a cache, record the fork generation. Before using the cache,
Expand All @@ -38,7 +38,7 @@ extern "C" {
//
// This is not reliably supported on all platforms which implement |fork|, so it
// should only be used as a hardening measure.
OPENSSL_EXPORT uint64_t CRYPTO_get_fork_generation(void);
OPENSSL_EXPORT uint64_t CRYPTO_get_fork_ube_generation(void);

// CRYPTO_fork_detect_ignore_wipeonfork_FOR_TESTING is an internal detail
// used for testing purposes.
Expand All @@ -53,4 +53,4 @@ OPENSSL_EXPORT void CRYPTO_fork_detect_ignore_inheritzero_FOR_TESTING(void);
} // extern C
#endif

#endif // OPENSSL_HEADER_CRYPTO_FORK_DETECT_H
#endif // OPENSSL_HEADER_CRYPTO_FORK_UBE_DETECT_H
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@

#include <gtest/gtest.h>

#include "fork_detect.h"
#include "fork_ube_detect.h"

#include "../test/test_util.h"

Expand All @@ -56,15 +56,15 @@ static pid_t WaitpidEINTR(pid_t pid, int *out_status, int options) {
// |stderr| and |_exit| rather than GTest.

static void CheckGenerationInChild(const char *name, uint64_t expected) {
uint64_t generation = CRYPTO_get_fork_generation();
uint64_t generation = CRYPTO_get_fork_ube_generation();
if (generation != expected) {
fprintf(stderr, "%s generation (#1) was %" PRIu64 ", wanted %" PRIu64 ".\n",
name, generation, expected);
_exit(1);
}

// The generation should be stable.
generation = CRYPTO_get_fork_generation();
generation = CRYPTO_get_fork_ube_generation();
if (generation != expected) {
fprintf(stderr, "%s generation (#2) was %" PRIu64 ", wanted %" PRIu64 ".\n",
name, generation, expected);
Expand Down Expand Up @@ -104,16 +104,16 @@ static void ForkInChild(std::function<void()> f) {

TEST(ForkDetect, Test) {

maybeDisableSomeForkDetectMechanisms();
maybeDisableSomeForkUbeDetectMechanisms();

const uint64_t start = CRYPTO_get_fork_generation();
const uint64_t start = CRYPTO_get_fork_ube_generation();
if (start == 0) {
fprintf(stderr, "Fork detection not supported. Skipping test.\n");
return;
}

// The fork generation should be stable.
EXPECT_EQ(start, CRYPTO_get_fork_generation());
EXPECT_EQ(start, CRYPTO_get_fork_ube_generation());

fflush(stderr);
const pid_t child = fork();
Expand Down Expand Up @@ -165,7 +165,7 @@ TEST(ForkDetect, Test) {
EXPECT_EQ(0, WEXITSTATUS(status)) << "Error in child process";

// We still observe |start|.
EXPECT_EQ(start, CRYPTO_get_fork_generation());
EXPECT_EQ(start, CRYPTO_get_fork_ube_generation());
}

#endif // OPENSSL_LINUX && !OPENSSL_TSAN
8 changes: 4 additions & 4 deletions crypto/ube/internal.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,12 @@ extern "C" {
// entries will immediately return.
OPENSSL_EXPORT int CRYPTO_get_ube_generation_number(uint64_t *current_generation_number);

// set_fork_generation_number_FOR_TESTING sets the fork generation number to the
// value |fork_gn|. This value will be the fork generation value used by the UBE
// logic, overriding the generation number from the real fork detection.
// set_fork_ube_generation_number_FOR_TESTING sets the fork generation number to
// the value |fork_gn|. This value will be the fork generation value used by the
// UBE logic, overriding the generation number from the real fork detection.
// |allow_mocked_ube_detection_FOR_TESTING| must have been invoked
// (once per-process) to allow mocking the fork generation number.
OPENSSL_EXPORT void set_fork_generation_number_FOR_TESTING(uint64_t fork_gn);
OPENSSL_EXPORT void set_fork_ube_generation_number_FOR_TESTING(uint64_t fork_gn);

// set_vm_ube_generation_number_FOR_TESTING sets the vm_ube generation
// number to the value |vm_ube_gn|. This value will be the vm_ube generation
Expand Down
Loading
Loading