tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

ProcessUtils_common.cpp (4854B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #include "ProcessUtils.h"
      8 
      9 #include "mozilla/Preferences.h"
     10 #include "mozilla/GeckoArgs.h"
     11 #include "mozilla/dom/RemoteType.h"
     12 #include "mozilla/ipc/GeckoChildProcessHost.h"
     13 #include "nsPrintfCString.h"
     14 
     15 #include "XPCSelfHostedShmem.h"
     16 
     17 namespace mozilla {
     18 namespace ipc {
     19 
     20 SharedPreferenceSerializer::SharedPreferenceSerializer() {
     21  MOZ_COUNT_CTOR(SharedPreferenceSerializer);
     22 }
     23 
     24 SharedPreferenceSerializer::~SharedPreferenceSerializer() {
     25  MOZ_COUNT_DTOR(SharedPreferenceSerializer);
     26 }
     27 
     28 SharedPreferenceSerializer::SharedPreferenceSerializer(
     29    SharedPreferenceSerializer&& aOther)
     30    : mPrefMapHandle(std::move(aOther.mPrefMapHandle)),
     31      mPrefsHandle(std::move(aOther.mPrefsHandle)) {
     32  MOZ_COUNT_CTOR(SharedPreferenceSerializer);
     33 }
     34 
     35 bool SharedPreferenceSerializer::SerializeToSharedMemory(
     36    const GeckoProcessType aDestinationProcessType,
     37    const nsACString& aDestinationRemoteType) {
     38  mPrefMapHandle = Preferences::EnsureSnapshot();
     39 
     40  bool destIsWebContent =
     41      aDestinationProcessType == GeckoProcessType_Content &&
     42      (StringBeginsWith(aDestinationRemoteType, WEB_REMOTE_TYPE) ||
     43       StringBeginsWith(aDestinationRemoteType, PREALLOC_REMOTE_TYPE));
     44 
     45  // Serialize the early prefs.
     46  nsAutoCStringN<1024> prefs;
     47  Preferences::SerializePreferences(prefs, destIsWebContent);
     48  auto prefsLength = prefs.Length();
     49 
     50  // Set up the shared memory.
     51  auto handle = shared_memory::Create(prefsLength);
     52  if (!handle) {
     53    NS_ERROR("failed to create shared memory in the parent");
     54    return false;
     55  }
     56  auto mapping = handle.Map();
     57  if (!mapping) {
     58    NS_ERROR("failed to map shared memory in the parent");
     59    return false;
     60  }
     61 
     62  // Copy the serialized prefs into the shared memory.
     63  memcpy(mapping.DataAs<char>(), prefs.get(), prefsLength);
     64 
     65  mPrefsHandle = std::move(handle).ToReadOnly();
     66  return true;
     67 }
     68 
     69 void SharedPreferenceSerializer::AddSharedPrefCmdLineArgs(
     70    mozilla::ipc::GeckoChildProcessHost& procHost,
     71    geckoargs::ChildProcessArgs& aExtraOpts) const {
     72  auto prefsHandle = GetPrefsHandle().Clone();
     73  MOZ_RELEASE_ASSERT(prefsHandle, "failed to clone prefs handle");
     74  auto prefMapHandle = GetPrefMapHandle().Clone();
     75  MOZ_RELEASE_ASSERT(prefMapHandle, "failed to clone pref map handle");
     76 
     77  // Pass the handles via command line flags.
     78  geckoargs::sPrefsHandle.Put(std::move(prefsHandle), aExtraOpts);
     79  geckoargs::sPrefMapHandle.Put(std::move(prefMapHandle), aExtraOpts);
     80 }
     81 
     82 SharedPreferenceDeserializer::SharedPreferenceDeserializer() {
     83  MOZ_COUNT_CTOR(SharedPreferenceDeserializer);
     84 }
     85 
     86 SharedPreferenceDeserializer::~SharedPreferenceDeserializer() {
     87  MOZ_COUNT_DTOR(SharedPreferenceDeserializer);
     88 }
     89 
     90 bool SharedPreferenceDeserializer::DeserializeFromSharedMemory(
     91    ReadOnlySharedMemoryHandle&& aPrefsHandle,
     92    ReadOnlySharedMemoryHandle&& aPrefMapHandle) {
     93  if (!aPrefsHandle || !aPrefMapHandle) {
     94    return false;
     95  }
     96 
     97  mPrefMapHandle = std::move(aPrefMapHandle);
     98 
     99  // Init the shared-memory base preference mapping first, so that only changed
    100  // preferences wind up in heap memory.
    101  Preferences::InitSnapshot(mPrefMapHandle);
    102 
    103  // Set up early prefs from the shared memory.
    104  mShmem = aPrefsHandle.Map();
    105  if (!mShmem) {
    106    NS_ERROR("failed to map shared memory in the child");
    107    return false;
    108  }
    109  Preferences::DeserializePreferences(mShmem.DataAs<char>(), mShmem.Size());
    110 
    111  return true;
    112 }
    113 
    114 void ExportSharedJSInit(mozilla::ipc::GeckoChildProcessHost& procHost,
    115                        geckoargs::ChildProcessArgs& aExtraOpts) {
    116  auto& shmem = xpc::SelfHostedShmem::GetSingleton();
    117  auto handle = shmem.Handle().Clone();
    118 
    119  // If the file is not found or the content is empty, then we would start the
    120  // content process without this optimization.
    121  if (!handle) {
    122    NS_ERROR("Can't use SelfHosted shared memory handle.");
    123    return;
    124  }
    125 
    126  // command line: -jsInitHandle handle
    127  geckoargs::sJsInitHandle.Put(std::move(handle), aExtraOpts);
    128 }
    129 
    130 bool ImportSharedJSInit(ReadOnlySharedMemoryHandle&& aJsInitHandle) {
    131  // This is an optimization, and as such we can safely recover if the command
    132  // line argument are not provided.
    133  if (!aJsInitHandle) {
    134    return true;
    135  }
    136 
    137  // Initialize the shared memory with the file handle and size of the content
    138  // of the self-hosted Xdr.
    139  auto& shmem = xpc::SelfHostedShmem::GetSingleton();
    140  if (!shmem.InitFromChild(std::move(aJsInitHandle))) {
    141    NS_ERROR("failed to open shared memory in the child");
    142    return false;
    143  }
    144 
    145  return true;
    146 }
    147 
    148 }  // namespace ipc
    149 }  // namespace mozilla