summaryrefslogtreecommitdiff
path: root/mojo/public/c
diff options
context:
space:
mode:
authorKen Rockot <rockot@chromium.org>2018-06-20 01:31:32 +0900
committerQijiang Fan <fqj@google.com>2020-06-05 09:44:16 +0900
commit72b203e3c6831a8f0ae9a407c9eb1d4deb07def9 (patch)
treea74406a3e01e5f31a777d9fe01e0cc517a615700 /mojo/public/c
parent0e9aec7be73a561e3c0554804a28e20b621f22f4 (diff)
downloadlibchrome-72b203e3c6831a8f0ae9a407c9eb1d4deb07def9.tar.gz
Fix and re-enable mojo_core_unittests on CFI bots
Adapts dynamic mojo_core library thunking to use base::ProtectedMemory for function table storage and exempts the calls from cfi-icall checks. Bug: 850464 Change-Id: I8e7d8dbcb4d312e089bdee830e89ed973ae5727e Reviewed-on: https://chromium-review.googlesource.com/1105301 Reviewed-by: Nico Weber <thakis@chromium.org> Reviewed-by: Jay Civelli <jcivelli@chromium.org> Commit-Queue: Ken Rockot <rockot@chromium.org> Cr-Commit-Position: refs/heads/master@{#568483} CrOS-Libchrome-Original-Commit: d929779dfb995e11090f2499f3a08e9c46daa18f
Diffstat (limited to 'mojo/public/c')
-rw-r--r--mojo/public/c/system/thunks.cc183
1 files changed, 103 insertions, 80 deletions
diff --git a/mojo/public/c/system/thunks.cc b/mojo/public/c/system/thunks.cc
index 38fc96688d..bcf0c6f988 100644
--- a/mojo/public/c/system/thunks.cc
+++ b/mojo/public/c/system/thunks.cc
@@ -10,6 +10,8 @@
#include "base/logging.h"
#include "base/macros.h"
+#include "base/memory/protected_memory.h"
+#include "base/memory/protected_memory_cfi.h"
#include "base/no_destructor.h"
#include "build/build_config.h"
#include "mojo/public/c/system/core.h"
@@ -24,10 +26,20 @@
namespace {
-MojoSystemThunks g_thunks = {0};
+typedef void (*MojoGetSystemThunksFunction)(MojoSystemThunks* thunks);
+
+#if defined(OS_CHROMEOS) || defined(OS_LINUX)
+PROTECTED_MEMORY_SECTION
+base::ProtectedMemory<MojoGetSystemThunksFunction> g_get_thunks;
+#endif
+
+PROTECTED_MEMORY_SECTION base::ProtectedMemory<MojoSystemThunks> g_thunks;
} // namespace
+#define INVOKE_THUNK(name, ...) \
+ base::UnsanitizedCfiCall(g_thunks, &MojoSystemThunks::name)(__VA_ARGS__)
+
namespace mojo {
// NOTE: This is defined within the global mojo namespace so that it can be
@@ -35,8 +47,6 @@ namespace mojo {
// enabled.
class CoreLibraryInitializer {
public:
- typedef void (*MojoGetSystemThunksFunction)(MojoSystemThunks* thunks);
-
CoreLibraryInitializer() {
#if defined(OS_CHROMEOS) || defined(OS_LINUX)
auto environment = base::Environment::Create();
@@ -61,16 +71,21 @@ class CoreLibraryInitializer {
<< "MOJO_CORE_LIBRARY_PATH environment variable.";
const char kGetThunksFunctionName[] = "MojoGetSystemThunks";
- MojoGetSystemThunksFunction get_thunks =
- reinterpret_cast<MojoGetSystemThunksFunction>(
- library_->GetFunctionPointer(kGetThunksFunctionName));
- CHECK(get_thunks) << "Invalid mojo_core library";
+ {
+ auto writer = base::AutoWritableMemory::Create(g_get_thunks);
+ *g_get_thunks = reinterpret_cast<MojoGetSystemThunksFunction>(
+ library_->GetFunctionPointer(kGetThunksFunctionName));
+ }
+ CHECK(*g_get_thunks) << "Invalid mojo_core library";
- DCHECK_EQ(g_thunks.size, 0u);
- g_thunks.size = sizeof(g_thunks);
- get_thunks(&g_thunks);
+ DCHECK_EQ(g_thunks->size, 0u);
+ {
+ auto writer = base::AutoWritableMemory::Create(g_thunks);
+ g_thunks->size = sizeof(*g_thunks);
+ base::UnsanitizedCfiCall(g_get_thunks)(&*g_thunks);
+ }
- CHECK_GT(g_thunks.size, 0u) << "Invalid mojo_core library";
+ CHECK_GT(g_thunks->size, 0u) << "Invalid mojo_core library";
#else // defined(OS_CHROMEOS) || defined(OS_LINUX)
NOTREACHED()
<< "Dynamic mojo_core loading is not supported on this platform.";
@@ -94,115 +109,118 @@ extern "C" {
MojoResult MojoInitialize(const struct MojoInitializeOptions* options) {
static base::NoDestructor<mojo::CoreLibraryInitializer> initializer;
ALLOW_UNUSED_LOCAL(initializer);
- DCHECK(g_thunks.Initialize);
+ DCHECK(g_thunks->Initialize);
- return g_thunks.Initialize(options);
+ return INVOKE_THUNK(Initialize, options);
}
MojoTimeTicks MojoGetTimeTicksNow() {
- return g_thunks.GetTimeTicksNow();
+ return INVOKE_THUNK(GetTimeTicksNow);
}
MojoResult MojoClose(MojoHandle handle) {
- return g_thunks.Close(handle);
+ return INVOKE_THUNK(Close, handle);
}
MojoResult MojoQueryHandleSignalsState(
MojoHandle handle,
struct MojoHandleSignalsState* signals_state) {
- return g_thunks.QueryHandleSignalsState(handle, signals_state);
+ return INVOKE_THUNK(QueryHandleSignalsState, handle, signals_state);
}
MojoResult MojoCreateMessagePipe(const MojoCreateMessagePipeOptions* options,
MojoHandle* message_pipe_handle0,
MojoHandle* message_pipe_handle1) {
- return g_thunks.CreateMessagePipe(options, message_pipe_handle0,
- message_pipe_handle1);
+ return INVOKE_THUNK(CreateMessagePipe, options, message_pipe_handle0,
+ message_pipe_handle1);
}
MojoResult MojoWriteMessage(MojoHandle message_pipe_handle,
MojoMessageHandle message_handle,
const MojoWriteMessageOptions* options) {
- return g_thunks.WriteMessage(message_pipe_handle, message_handle, options);
+ return INVOKE_THUNK(WriteMessage, message_pipe_handle, message_handle,
+ options);
}
MojoResult MojoReadMessage(MojoHandle message_pipe_handle,
const MojoReadMessageOptions* options,
MojoMessageHandle* message_handle) {
- return g_thunks.ReadMessage(message_pipe_handle, options, message_handle);
+ return INVOKE_THUNK(ReadMessage, message_pipe_handle, options,
+ message_handle);
}
MojoResult MojoFuseMessagePipes(MojoHandle handle0,
MojoHandle handle1,
const MojoFuseMessagePipesOptions* options) {
- return g_thunks.FuseMessagePipes(handle0, handle1, options);
+ return INVOKE_THUNK(FuseMessagePipes, handle0, handle1, options);
}
MojoResult MojoCreateDataPipe(const MojoCreateDataPipeOptions* options,
MojoHandle* data_pipe_producer_handle,
MojoHandle* data_pipe_consumer_handle) {
- return g_thunks.CreateDataPipe(options, data_pipe_producer_handle,
- data_pipe_consumer_handle);
+ return INVOKE_THUNK(CreateDataPipe, options, data_pipe_producer_handle,
+ data_pipe_consumer_handle);
}
MojoResult MojoWriteData(MojoHandle data_pipe_producer_handle,
const void* elements,
uint32_t* num_elements,
const MojoWriteDataOptions* options) {
- return g_thunks.WriteData(data_pipe_producer_handle, elements, num_elements,
- options);
+ return INVOKE_THUNK(WriteData, data_pipe_producer_handle, elements,
+ num_elements, options);
}
MojoResult MojoBeginWriteData(MojoHandle data_pipe_producer_handle,
const MojoBeginWriteDataOptions* options,
void** buffer,
uint32_t* buffer_num_elements) {
- return g_thunks.BeginWriteData(data_pipe_producer_handle, options, buffer,
- buffer_num_elements);
+ return INVOKE_THUNK(BeginWriteData, data_pipe_producer_handle, options,
+ buffer, buffer_num_elements);
}
MojoResult MojoEndWriteData(MojoHandle data_pipe_producer_handle,
uint32_t num_elements_written,
const MojoEndWriteDataOptions* options) {
- return g_thunks.EndWriteData(data_pipe_producer_handle, num_elements_written,
- options);
+ return INVOKE_THUNK(EndWriteData, data_pipe_producer_handle,
+ num_elements_written, options);
}
MojoResult MojoReadData(MojoHandle data_pipe_consumer_handle,
const MojoReadDataOptions* options,
void* elements,
uint32_t* num_elements) {
- return g_thunks.ReadData(data_pipe_consumer_handle, options, elements,
- num_elements);
+ return INVOKE_THUNK(ReadData, data_pipe_consumer_handle, options, elements,
+ num_elements);
}
MojoResult MojoBeginReadData(MojoHandle data_pipe_consumer_handle,
const MojoBeginReadDataOptions* options,
const void** buffer,
uint32_t* buffer_num_elements) {
- return g_thunks.BeginReadData(data_pipe_consumer_handle, options, buffer,
- buffer_num_elements);
+ return INVOKE_THUNK(BeginReadData, data_pipe_consumer_handle, options, buffer,
+ buffer_num_elements);
}
MojoResult MojoEndReadData(MojoHandle data_pipe_consumer_handle,
uint32_t num_elements_read,
const MojoEndReadDataOptions* options) {
- return g_thunks.EndReadData(data_pipe_consumer_handle, num_elements_read,
- options);
+ return INVOKE_THUNK(EndReadData, data_pipe_consumer_handle, num_elements_read,
+ options);
}
MojoResult MojoCreateSharedBuffer(uint64_t num_bytes,
const MojoCreateSharedBufferOptions* options,
MojoHandle* shared_buffer_handle) {
- return g_thunks.CreateSharedBuffer(num_bytes, options, shared_buffer_handle);
+ return INVOKE_THUNK(CreateSharedBuffer, num_bytes, options,
+ shared_buffer_handle);
}
MojoResult MojoDuplicateBufferHandle(
MojoHandle buffer_handle,
const MojoDuplicateBufferHandleOptions* options,
MojoHandle* new_buffer_handle) {
- return g_thunks.DuplicateBufferHandle(buffer_handle, options,
- new_buffer_handle);
+ return INVOKE_THUNK(DuplicateBufferHandle, buffer_handle, options,
+ new_buffer_handle);
}
MojoResult MojoMapBuffer(MojoHandle buffer_handle,
@@ -210,23 +228,24 @@ MojoResult MojoMapBuffer(MojoHandle buffer_handle,
uint64_t num_bytes,
const MojoMapBufferOptions* options,
void** buffer) {
- return g_thunks.MapBuffer(buffer_handle, offset, num_bytes, options, buffer);
+ return INVOKE_THUNK(MapBuffer, buffer_handle, offset, num_bytes, options,
+ buffer);
}
MojoResult MojoUnmapBuffer(void* buffer) {
- return g_thunks.UnmapBuffer(buffer);
+ return INVOKE_THUNK(UnmapBuffer, buffer);
}
MojoResult MojoGetBufferInfo(MojoHandle buffer_handle,
const MojoGetBufferInfoOptions* options,
MojoSharedBufferInfo* info) {
- return g_thunks.GetBufferInfo(buffer_handle, options, info);
+ return INVOKE_THUNK(GetBufferInfo, buffer_handle, options, info);
}
MojoResult MojoCreateTrap(MojoTrapEventHandler handler,
const MojoCreateTrapOptions* options,
MojoHandle* trap_handle) {
- return g_thunks.CreateTrap(handler, options, trap_handle);
+ return INVOKE_THUNK(CreateTrap, handler, options, trap_handle);
}
MojoResult MojoAddTrigger(MojoHandle trap_handle,
@@ -235,14 +254,14 @@ MojoResult MojoAddTrigger(MojoHandle trap_handle,
MojoTriggerCondition condition,
uintptr_t context,
const MojoAddTriggerOptions* options) {
- return g_thunks.AddTrigger(trap_handle, handle, signals, condition, context,
- options);
+ return INVOKE_THUNK(AddTrigger, trap_handle, handle, signals, condition,
+ context, options);
}
MojoResult MojoRemoveTrigger(MojoHandle trap_handle,
uintptr_t context,
const MojoRemoveTriggerOptions* options) {
- return g_thunks.RemoveTrigger(trap_handle, context, options);
+ return INVOKE_THUNK(RemoveTrigger, trap_handle, context, options);
}
MojoResult MojoArmTrap(MojoHandle trap_handle,
@@ -251,22 +270,22 @@ MojoResult MojoArmTrap(MojoHandle trap_handle,
uintptr_t* ready_triggers,
MojoResult* ready_results,
MojoHandleSignalsState* ready_signals_states) {
- return g_thunks.ArmTrap(trap_handle, options, num_ready_triggers,
- ready_triggers, ready_results, ready_signals_states);
+ return INVOKE_THUNK(ArmTrap, trap_handle, options, num_ready_triggers,
+ ready_triggers, ready_results, ready_signals_states);
}
MojoResult MojoCreateMessage(const MojoCreateMessageOptions* options,
MojoMessageHandle* message) {
- return g_thunks.CreateMessage(options, message);
+ return INVOKE_THUNK(CreateMessage, options, message);
}
MojoResult MojoDestroyMessage(MojoMessageHandle message) {
- return g_thunks.DestroyMessage(message);
+ return INVOKE_THUNK(DestroyMessage, message);
}
MojoResult MojoSerializeMessage(MojoMessageHandle message,
const MojoSerializeMessageOptions* options) {
- return g_thunks.SerializeMessage(message, options);
+ return INVOKE_THUNK(SerializeMessage, message, options);
}
MojoResult MojoAppendMessageData(MojoMessageHandle message,
@@ -276,8 +295,8 @@ MojoResult MojoAppendMessageData(MojoMessageHandle message,
const MojoAppendMessageDataOptions* options,
void** buffer,
uint32_t* buffer_size) {
- return g_thunks.AppendMessageData(message, payload_size, handles, num_handles,
- options, buffer, buffer_size);
+ return INVOKE_THUNK(AppendMessageData, message, payload_size, handles,
+ num_handles, options, buffer, buffer_size);
}
MojoResult MojoGetMessageData(MojoMessageHandle message,
@@ -286,8 +305,8 @@ MojoResult MojoGetMessageData(MojoMessageHandle message,
uint32_t* num_bytes,
MojoHandle* handles,
uint32_t* num_handles) {
- return g_thunks.GetMessageData(message, options, buffer, num_bytes, handles,
- num_handles);
+ return INVOKE_THUNK(GetMessageData, message, options, buffer, num_bytes,
+ handles, num_handles);
}
MojoResult MojoSetMessageContext(MojoMessageHandle message,
@@ -295,34 +314,37 @@ MojoResult MojoSetMessageContext(MojoMessageHandle message,
MojoMessageContextSerializer serializer,
MojoMessageContextDestructor destructor,
const MojoSetMessageContextOptions* options) {
- return g_thunks.SetMessageContext(message, context, serializer, destructor,
- options);
+ return INVOKE_THUNK(SetMessageContext, message, context, serializer,
+ destructor, options);
}
MojoResult MojoGetMessageContext(MojoMessageHandle message,
const MojoGetMessageContextOptions* options,
uintptr_t* context) {
- return g_thunks.GetMessageContext(message, options, context);
+ return INVOKE_THUNK(GetMessageContext, message, options, context);
}
MojoResult MojoNotifyBadMessage(MojoMessageHandle message,
const char* error,
uint32_t error_num_bytes,
const MojoNotifyBadMessageOptions* options) {
- return g_thunks.NotifyBadMessage(message, error, error_num_bytes, options);
+ return INVOKE_THUNK(NotifyBadMessage, message, error, error_num_bytes,
+ options);
}
MojoResult MojoWrapPlatformHandle(const MojoPlatformHandle* platform_handle,
const MojoWrapPlatformHandleOptions* options,
MojoHandle* mojo_handle) {
- return g_thunks.WrapPlatformHandle(platform_handle, options, mojo_handle);
+ return INVOKE_THUNK(WrapPlatformHandle, platform_handle, options,
+ mojo_handle);
}
MojoResult MojoUnwrapPlatformHandle(
MojoHandle mojo_handle,
const MojoUnwrapPlatformHandleOptions* options,
MojoPlatformHandle* platform_handle) {
- return g_thunks.UnwrapPlatformHandle(mojo_handle, options, platform_handle);
+ return INVOKE_THUNK(UnwrapPlatformHandle, mojo_handle, options,
+ platform_handle);
}
MojoResult MojoWrapPlatformSharedMemoryRegion(
@@ -333,9 +355,9 @@ MojoResult MojoWrapPlatformSharedMemoryRegion(
MojoPlatformSharedMemoryRegionAccessMode access_mode,
const MojoWrapPlatformSharedMemoryRegionOptions* options,
MojoHandle* mojo_handle) {
- return g_thunks.WrapPlatformSharedMemoryRegion(
- platform_handles, num_platform_handles, num_bytes, guid, access_mode,
- options, mojo_handle);
+ return INVOKE_THUNK(WrapPlatformSharedMemoryRegion, platform_handles,
+ num_platform_handles, num_bytes, guid, access_mode,
+ options, mojo_handle);
}
MojoResult MojoUnwrapPlatformSharedMemoryRegion(
@@ -346,14 +368,14 @@ MojoResult MojoUnwrapPlatformSharedMemoryRegion(
uint64_t* num_bytes,
struct MojoSharedBufferGuid* guid,
MojoPlatformSharedMemoryRegionAccessMode* access_mode) {
- return g_thunks.UnwrapPlatformSharedMemoryRegion(
- mojo_handle, options, platform_handles, num_platform_handles, num_bytes,
- guid, access_mode);
+ return INVOKE_THUNK(UnwrapPlatformSharedMemoryRegion, mojo_handle, options,
+ platform_handles, num_platform_handles, num_bytes, guid,
+ access_mode);
}
MojoResult MojoCreateInvitation(const MojoCreateInvitationOptions* options,
MojoHandle* invitation_handle) {
- return g_thunks.CreateInvitation(options, invitation_handle);
+ return INVOKE_THUNK(CreateInvitation, options, invitation_handle);
}
MojoResult MojoAttachMessagePipeToInvitation(
@@ -362,8 +384,8 @@ MojoResult MojoAttachMessagePipeToInvitation(
uint32_t name_num_bytes,
const MojoAttachMessagePipeToInvitationOptions* options,
MojoHandle* message_pipe_handle) {
- return g_thunks.AttachMessagePipeToInvitation(
- invitation_handle, name, name_num_bytes, options, message_pipe_handle);
+ return INVOKE_THUNK(AttachMessagePipeToInvitation, invitation_handle, name,
+ name_num_bytes, options, message_pipe_handle);
}
MojoResult MojoExtractMessagePipeFromInvitation(
@@ -372,8 +394,8 @@ MojoResult MojoExtractMessagePipeFromInvitation(
uint32_t name_num_bytes,
const MojoExtractMessagePipeFromInvitationOptions* options,
MojoHandle* message_pipe_handle) {
- return g_thunks.ExtractMessagePipeFromInvitation(
- invitation_handle, name, name_num_bytes, options, message_pipe_handle);
+ return INVOKE_THUNK(ExtractMessagePipeFromInvitation, invitation_handle, name,
+ name_num_bytes, options, message_pipe_handle);
}
MojoResult MojoSendInvitation(
@@ -383,17 +405,17 @@ MojoResult MojoSendInvitation(
MojoProcessErrorHandler error_handler,
uintptr_t error_handler_context,
const MojoSendInvitationOptions* options) {
- return g_thunks.SendInvitation(invitation_handle, process_handle,
- transport_endpoint, error_handler,
- error_handler_context, options);
+ return INVOKE_THUNK(SendInvitation, invitation_handle, process_handle,
+ transport_endpoint, error_handler, error_handler_context,
+ options);
}
MojoResult MojoAcceptInvitation(
const MojoInvitationTransportEndpoint* transport_endpoint,
const MojoAcceptInvitationOptions* options,
MojoHandle* invitation_handle) {
- return g_thunks.AcceptInvitation(transport_endpoint, options,
- invitation_handle);
+ return INVOKE_THUNK(AcceptInvitation, transport_endpoint, options,
+ invitation_handle);
}
} // extern "C"
@@ -401,13 +423,14 @@ MojoResult MojoAcceptInvitation(
void MojoEmbedderSetSystemThunks(const MojoSystemThunks* thunks) {
// Assume embedders will always use matching versions of the EDK and public
// APIs.
- DCHECK_EQ(thunks->size, sizeof(g_thunks));
+ DCHECK_EQ(thunks->size, sizeof(*g_thunks));
- // This should only have to check that the |g_thunks.size| is zero, but we
+ // This should only have to check that the |g_thunks->size| is zero, but we
// have multiple EDK initializations in some test suites still. For now we
// allow double calls as long as they're the same thunks as before.
- DCHECK(g_thunks.size == 0 || !memcmp(&g_thunks, thunks, sizeof(g_thunks)))
+ DCHECK(g_thunks->size == 0 || !memcmp(&*g_thunks, thunks, sizeof(*g_thunks)))
<< "Cannot set embedder thunks after Mojo API calls have been made.";
- g_thunks = *thunks;
+ auto writer = base::AutoWritableMemory::Create(g_thunks);
+ *g_thunks = *thunks;
}