diff options
author | Ken Rockot <rockot@chromium.org> | 2018-06-20 01:31:32 +0900 |
---|---|---|
committer | Qijiang Fan <fqj@google.com> | 2020-06-05 09:44:16 +0900 |
commit | 72b203e3c6831a8f0ae9a407c9eb1d4deb07def9 (patch) | |
tree | a74406a3e01e5f31a777d9fe01e0cc517a615700 /mojo/public/c | |
parent | 0e9aec7be73a561e3c0554804a28e20b621f22f4 (diff) | |
download | libchrome-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.cc | 183 |
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; } |