diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-10-12 14:27:29 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-10-13 09:35:20 +0000 |
commit | c30a6232df03e1efbd9f3b226777b07e087a1122 (patch) | |
tree | e992f45784689f373bcc38d1b79a239ebe17ee23 /chromium/mojo/public/c/system | |
parent | 7b5b123ac58f58ffde0f4f6e488bcd09aa4decd3 (diff) | |
download | qtwebengine-chromium-85-based.tar.gz |
BASELINE: Update Chromium to 85.0.4183.14085-based
Change-Id: Iaa42f4680837c57725b1344f108c0196741f6057
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/mojo/public/c/system')
-rw-r--r-- | chromium/mojo/public/c/system/functions.h | 18 | ||||
-rw-r--r-- | chromium/mojo/public/c/system/invitation.h | 50 | ||||
-rw-r--r-- | chromium/mojo/public/c/system/macros.h | 13 | ||||
-rw-r--r-- | chromium/mojo/public/c/system/thunks.cc | 92 | ||||
-rw-r--r-- | chromium/mojo/public/c/system/thunks.h | 5 | ||||
-rw-r--r-- | chromium/mojo/public/c/system/types.h | 44 |
6 files changed, 178 insertions, 44 deletions
diff --git a/chromium/mojo/public/c/system/functions.h b/chromium/mojo/public/c/system/functions.h index 6f47028f480..257b6012c74 100644 --- a/chromium/mojo/public/c/system/functions.h +++ b/chromium/mojo/public/c/system/functions.h @@ -12,6 +12,7 @@ #include <stddef.h> #include <stdint.h> +#include "mojo/public/c/system/invitation.h" #include "mojo/public/c/system/system_export.h" #include "mojo/public/c/system/types.h" @@ -26,12 +27,23 @@ extern "C" { // // |options| may be null. // +// If the |MOJO_INITIALIZE_FLAG_LOAD_ONLY| flag is given in |options|, this only +// partially initializes the library. Other Mojo APIs will remain unavailable +// until the library is fully initialized by a subsequent call to +// |MojoInitialize()| WITHOUT the flag. See documentation on +// |MOJO_INITIALIZE_FLAG_LOAD_ONLY| in types.h for details. +// // Returns: // |MOJO_RESULT_OK| if Mojo initialization was successful. +// |MOJO_RESULT_NOT_FOUND| if the Mojo Core library could not be loaded or +// appears to be malformed. +// |MOJO_RESULT_FAILED_PRECONDITION| if the Mojo Core library AND full IPC +// support has already been initialized by some prior call(s) to +// |MojoInitialize()|. +// |MOJO_RESULT_ALREADY_EXISTS| if |MOJO_INITIALIZE_FLAG_LOAD_ONLY| was +// specified for this call but the library has already been successfully +// loaded and partially initialized by a previous call with the same flag. // |MOJO_RESULT_INVALID_ARGUMENT| if |options| was non-null and invalid. -// |MOJO_RESULT_FAILED_PRECONDITION| if |MojoInitialize()| was already called -// once or if the application already explicitly initialized a Mojo Core -// environment as an embedder. MOJO_SYSTEM_EXPORT MojoResult MojoInitialize(const struct MojoInitializeOptions* options); diff --git a/chromium/mojo/public/c/system/invitation.h b/chromium/mojo/public/c/system/invitation.h index e63001eb0be..f95bcc4e096 100644 --- a/chromium/mojo/public/c/system/invitation.h +++ b/chromium/mojo/public/c/system/invitation.h @@ -251,6 +251,25 @@ struct MOJO_ALIGNAS(8) MojoAcceptInvitationOptions { MOJO_STATIC_ASSERT(sizeof(struct MojoAcceptInvitationOptions) == 8, "MojoAcceptInvitationOptions has wrong size"); +// Flags passed to |MojoSetDefaultProcessErrorHandler()| via +// |MojoSetDefaultProcessErrorHandlerOptions|. +typedef uint32_t MojoSetDefaultProcessErrorHandlerFlags; + +// No flags. Default behavior. +#define MOJO_SET_DEFAULT_PROCESS_ERROR_HANDLER_FLAG_NONE \ + ((MojoSetDefaultProcessErrorHandlerFlags)0) + +// Options passed to |MojoSetDefaultProcessErrorHandler()|. +struct MOJO_ALIGNAS(8) MojoSetDefaultProcessErrorHandlerOptions { + // The size of this structure, used for versioning. + uint32_t struct_size; + + // See |MojoSetDefaultProcessErrorHandlerFlags|. + MojoSetDefaultProcessErrorHandlerFlags flags; +}; +MOJO_STATIC_ASSERT(sizeof(struct MojoSetDefaultProcessErrorHandlerOptions) == 8, + "MojoSetDefaultProcessErrorHandlerOptions has wrong size"); + #ifdef __cplusplus extern "C" { #endif @@ -266,6 +285,12 @@ typedef void (*MojoProcessErrorHandler)( uintptr_t context, const struct MojoProcessErrorDetails* details); +// Similar to above, but registered globally via +// |MojoSetDefaultProcessErrorHandler()| and invoked only for communication +// errors regarding processes NOT invited by the calling process. +typedef void (*MojoDefaultProcessErrorHandler)( + const struct MojoProcessErrorDetails* details); + // Creates a new invitation to be sent to another process. // // An invitation is used to invite another process to join this process's @@ -474,6 +499,31 @@ MOJO_SYSTEM_EXPORT MojoResult MojoAcceptInvitation( const struct MojoAcceptInvitationOptions* options, MojoHandle* invitation_handle); +// Registers a process-wide handler to be invoked when an error is raised on a +// connection to a peer process. Such errors can be raised if the peer process +// sends malformed data to this process. +// +// Note that this handler is only invoked for connections to processes NOT +// explicitly invited by this process. To handle errors concerning processes +// invited by this process, see the MojoProcessErrorHandler argument to +// |MojoSendInvitation()|. +// +// The general use case for this API is to be able to log or report instances of +// bad IPCs received by a client process which no real ability or authority to +// identify the source. +// +// Returns: +// |MOJO_RESULT_OK| if |handler| is successfully registered as the global +// default process error handler within the calling process. If |handler| +// is null, any registered default process error handler is removed. +// |MOJO_RESULT_ALREADY_EXISTS| if |handler| is non-null and there is already +// a registered error handler. Callers wishing to replace an existing +// handler must first call |MojoSetDefaultProcessErrorHandler()| with null +// in order to do so. +MOJO_SYSTEM_EXPORT MojoResult MojoSetDefaultProcessErrorHandler( + MojoDefaultProcessErrorHandler handler, + const struct MojoSetDefaultProcessErrorHandlerOptions* options); + #ifdef __cplusplus } // extern "C" #endif diff --git a/chromium/mojo/public/c/system/macros.h b/chromium/mojo/public/c/system/macros.h index 1023e1c111a..ebacb7482ac 100644 --- a/chromium/mojo/public/c/system/macros.h +++ b/chromium/mojo/public/c/system/macros.h @@ -6,6 +6,7 @@ #define MOJO_PUBLIC_C_SYSTEM_MACROS_H_ #include <stddef.h> +#include <stdint.h> #if !defined(__cplusplus) #include <assert.h> // Defines static_assert() in C11. @@ -29,6 +30,18 @@ // Like the C++11 |alignof| operator. #define MOJO_ALIGNOF(type) alignof(type) +// Provides a convenient test for the presence of a field in a user-provided +// structure from a potentially older version of the ABI. Presence is determined +// by comparing the struct's provided |struct_size| value against the known +// offset and size of the field in this version of the ABI. Because fields are +// never reordered or removed, this is a sufficient test for the field's +// presence within whatever version of the ABI the client is programmed against. +#define MOJO_IS_STRUCT_FIELD_PRESENT(struct_pointer, field) \ + ((size_t)(uintptr_t)((const char*)&(struct_pointer)->field - \ + (const char*)(struct_pointer)) + \ + sizeof((struct_pointer)->field) <= \ + (struct_pointer)->struct_size) + // Specify the alignment of a |struct|, etc. // Use like: // struct MOJO_ALIGNAS(8) Foo { ... }; diff --git a/chromium/mojo/public/c/system/thunks.cc b/chromium/mojo/public/c/system/thunks.cc index 1bf1a2673d7..6a67df5e710 100644 --- a/chromium/mojo/public/c/system/thunks.cc +++ b/chromium/mojo/public/c/system/thunks.cc @@ -8,12 +8,17 @@ #include <cstdint> #include <cstring> +#include "base/check_op.h" #include "base/compiler_specific.h" +#include "base/files/file_path.h" #include "base/logging.h" #include "base/macros.h" #include "base/no_destructor.h" +#include "base/notreached.h" +#include "base/strings/string_piece.h" #include "build/build_config.h" #include "mojo/public/c/system/core.h" +#include "mojo/public/c/system/macros.h" #if defined(OS_CHROMEOS) || defined(OS_LINUX) || defined(OS_WIN) #include "base/environment.h" @@ -57,17 +62,17 @@ namespace mojo { // enabled. class CoreLibraryInitializer { public: - CoreLibraryInitializer(const MojoInitializeOptions* options) { + CoreLibraryInitializer() = default; + CoreLibraryInitializer(const CoreLibraryInitializer&) = delete; + CoreLibraryInitializer& operator=(const CoreLibraryInitializer&) = delete; + ~CoreLibraryInitializer() = default; + + MojoResult LoadLibrary(base::FilePath library_path) { #if defined(OS_CHROMEOS) || defined(OS_LINUX) || defined(OS_WIN) - bool application_provided_path = false; - base::Optional<base::FilePath> library_path; - if (options && options->struct_size >= sizeof(*options) && - options->mojo_core_path) { - base::StringPiece utf8_path(options->mojo_core_path, - options->mojo_core_path_length); - library_path.emplace(base::FilePath::FromUTF8Unsafe(utf8_path)); - application_provided_path = true; - } else { + if (library_ && library_->is_valid()) + return MOJO_RESULT_OK; + + if (library_path.empty()) { auto environment = base::Environment::Create(); std::string library_path_value; const char kLibraryPathEnvironmentVar[] = "MOJO_CORE_LIBRARY_PATH"; @@ -75,7 +80,7 @@ class CoreLibraryInitializer { library_path = base::FilePath::FromUTF8Unsafe(library_path_value); } - if (!library_path) { + if (library_path.empty()) { // Default to looking for the library in the current working directory. #if defined(OS_CHROMEOS) || defined(OS_LINUX) const base::FilePath::CharType kDefaultLibraryPathValue[] = @@ -84,7 +89,7 @@ class CoreLibraryInitializer { const base::FilePath::CharType kDefaultLibraryPathValue[] = FILE_PATH_LITERAL("mojo_core.dll"); #endif - library_path.emplace(kDefaultLibraryPathValue); + library_path = base::FilePath(kDefaultLibraryPathValue); } // NOTE: |prefer_own_symbols| on POSIX implies that the library is loaded @@ -100,47 +105,36 @@ class CoreLibraryInitializer { // allocator shims, so it's unnecessary there. library_options.prefer_own_symbols = true; #endif - library_.emplace(base::LoadNativeLibraryWithOptions( - *library_path, library_options, nullptr)); - if (!application_provided_path) { - CHECK(library_->is_valid()) - << "Unable to load the mojo_core library. Make sure the library is " - << "in the working directory or is correctly pointed to by the " - << "MOJO_CORE_LIBRARY_PATH environment variable."; - } else { - CHECK(library_->is_valid()) - << "Unable to locate mojo_core library. This application expects to " - << "find it at " << library_path->value(); - } + base::ScopedNativeLibrary library(base::LoadNativeLibraryWithOptions( + library_path, library_options, nullptr)); + if (!library.is_valid()) + return MOJO_RESULT_NOT_FOUND; const char kGetThunksFunctionName[] = "MojoGetSystemThunks"; MojoGetSystemThunksFunction g_get_thunks = reinterpret_cast<MojoGetSystemThunksFunction>( - library_->GetFunctionPointer(kGetThunksFunctionName)); - CHECK(g_get_thunks) << "Invalid mojo_core library: " - << library_path->value(); + library.GetFunctionPointer(kGetThunksFunctionName)); + if (!g_get_thunks) + return MOJO_RESULT_NOT_FOUND; DCHECK_EQ(g_thunks.size, 0u); g_thunks.size = sizeof(g_thunks); g_get_thunks(&g_thunks); + if (g_thunks.size == 0) + return MOJO_RESULT_NOT_FOUND; - CHECK_GT(g_thunks.size, 0u) - << "Invalid mojo_core library: " << library_path->value(); -#else // defined(OS_CHROMEOS) || defined(OS_LINUX) - NOTREACHED() - << "Dynamic mojo_core loading is not supported on this platform."; -#endif // defined(OS_CHROMEOS) || defined(OS_LINUX) + library_ = std::move(library); + return MOJO_RESULT_OK; +#else // defined(OS_CHROMEOS) || defined(OS_LINUX) || defined(OS_WIN) + return MOJO_RESULT_UNIMPLEMENTED; +#endif // defined(OS_CHROMEOS) || defined(OS_LINUX) || defined(OS_WIN) } - ~CoreLibraryInitializer() = default; - private: #if defined(OS_CHROMEOS) || defined(OS_LINUX) || defined(OS_WIN) base::Optional<base::ScopedNativeLibrary> library_; #endif - - DISALLOW_COPY_AND_ASSIGN(CoreLibraryInitializer); }; } // namespace mojo @@ -148,10 +142,22 @@ class CoreLibraryInitializer { extern "C" { MojoResult MojoInitialize(const struct MojoInitializeOptions* options) { - static base::NoDestructor<mojo::CoreLibraryInitializer> initializer(options); - ALLOW_UNUSED_LOCAL(initializer); - DCHECK(g_thunks.Initialize); + static base::NoDestructor<mojo::CoreLibraryInitializer> initializer; + + base::StringPiece library_path_utf8; + if (options) { + if (!MOJO_IS_STRUCT_FIELD_PRESENT(options, mojo_core_path_length)) + return MOJO_RESULT_INVALID_ARGUMENT; + library_path_utf8 = base::StringPiece(options->mojo_core_path, + options->mojo_core_path_length); + } + + MojoResult load_result = initializer->LoadLibrary( + base::FilePath::FromUTF8Unsafe(library_path_utf8)); + if (load_result != MOJO_RESULT_OK) + return load_result; + DCHECK(g_thunks.Initialize); return INVOKE_THUNK(Initialize, options); } @@ -476,6 +482,12 @@ MojoResult MojoShutdown(const MojoShutdownOptions* options) { return INVOKE_THUNK(Shutdown, options); } +MojoResult MojoSetDefaultProcessErrorHandler( + MojoDefaultProcessErrorHandler handler, + const struct MojoSetDefaultProcessErrorHandlerOptions* options) { + return INVOKE_THUNK(SetDefaultProcessErrorHandler, handler, options); +} + } // extern "C" void MojoEmbedderSetSystemThunks(const MojoSystemThunks* thunks) { diff --git a/chromium/mojo/public/c/system/thunks.h b/chromium/mojo/public/c/system/thunks.h index f3f9742a8bf..4b41b939e24 100644 --- a/chromium/mojo/public/c/system/thunks.h +++ b/chromium/mojo/public/c/system/thunks.h @@ -228,6 +228,11 @@ struct MojoSystemThunks { // Core ABI version 2 additions begin here. MojoResult (*Shutdown)(const struct MojoShutdownOptions* options); + + // Core ABI version 3 additions begin here. + MojoResult (*SetDefaultProcessErrorHandler)( + MojoDefaultProcessErrorHandler handler, + const struct MojoSetDefaultProcessErrorHandlerOptions* options); }; #pragma pack(pop) diff --git a/chromium/mojo/public/c/system/types.h b/chromium/mojo/public/c/system/types.h index cee529f1dac..bb6504343a7 100644 --- a/chromium/mojo/public/c/system/types.h +++ b/chromium/mojo/public/c/system/types.h @@ -147,8 +147,38 @@ typedef uint32_t MojoInitializeFlags; // process. That process is always the first member of the network and it should // set this flag during initialization. Attempts to invite a broker process into // an existing network will always fail. +// +// This flag is ignored when |MOJO_INITIALIZE_FLAG_LOAD_ONLY| is set. #define MOJO_INITIALIZE_FLAG_AS_BROKER ((MojoInitializeFlags)1) +// Even if not initialized as the broker process, the calling process will be +// configured for direct shared memory allocation. This can be used for +// non-broker processes which are still sufficiently privileged to allocate +// their own shared memory. +// +// This flag is ignored when |MOJO_INITIALIZE_FLAG_LOAD_ONLY| is set. +#define MOJO_INITIALIZE_FLAG_FORCE_DIRECT_SHARED_MEMORY_ALLOCATION \ + ((MojoInitializeFlags)2) + +// This call to |MojoInitialize()| should NOT fully initialize Mojo's internal +// IPC support engine. Initialization is essentially a two-phase operation: +// first the library is loaded and its global state is initialized, and then +// full IPC support is initialized. The latter phase may spawn a background +// thread, thus making it hostile to certain scenarios (e.g. prior to a fork() +// on Linux et al); meanwhile the former phase may still need to be completed +// early, e.g. prior to some sandbox configuration which may precede a fork(). +// +// Applications wishing to separate initialization into two phases can set +// this flag during an initial call to |MojoInitialize()|. To subsequently +// enable use of all Mojo APIs, |MojoInitialize()| must be called another time, +// without this flag set. +// +// Note that various MojoInitializeOptions may be ignored on the second call +// to |MojoInitialize()|, while others may actually override options passed to +// the first call. Documentation on individual option fields and flags clarifies +// this behavior. +#define MOJO_INITIALIZE_FLAG_LOAD_ONLY ((MojoInitializeFlags)4) + // Options passed to |MojoInitialize()|. struct MOJO_ALIGNAS(8) MojoInitializeOptions { // The size of this structure, used for versioning. @@ -161,10 +191,22 @@ struct MOJO_ALIGNAS(8) MojoInitializeOptions { // to load. If the |mojo_core_path| is null then |mojo_core_path_length| is // ignored and Mojo will fall back first onto the |MOJO_CORE_LIBRARY_PATH| // environment variable, and then onto the current working directory. + // + // NOTE: These fields are only observed during the first successful call to + // |MojoInitialize()| in a process. MOJO_POINTER_FIELD(const char*, mojo_core_path); uint32_t mojo_core_path_length; + + // For POSIX and Fuchsia systems only, this is the |argc| and |argv| from + // the calling process's main() entry point. These fields are ignored on + // Windows, but we define them anyway for the sake of ABI consistency. + // + // NOTE: These fields are only observed during the first successful call to + // |MojoInitialize()| within a process. + int32_t argc; + MOJO_POINTER_FIELD(const char* const*, argv); }; -MOJO_STATIC_ASSERT(sizeof(struct MojoInitializeOptions) == 24, +MOJO_STATIC_ASSERT(sizeof(struct MojoInitializeOptions) == 32, "MojoInitializeOptions has wrong size"); // Flags passed to |MojoShutdown()| via |MojoShutdownOptions|. |