Bug 996996 - Move fopen into non-sanboxed process. r=mrbkap
authorAlphan Chen<alchen@mozilla.com>
Wed, 21 May 2014 13:49:36 +0800
changeset 184121 afe8ef1b62d138cf3c13833be8c0d7d4cd132d7e
parent 184120 5a562c4ceb494f20d15e7c698b9ca7430ccd7966
child 184122 b34ba09e0391f1cbff3b3255e09d898978214ec5
push id6897
push userryanvm@gmail.com
push dateWed, 21 May 2014 12:56:42 +0000
treeherderfx-team@a971ac323875 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmrbkap
bugs996996
milestone32.0a1
Bug 996996 - Move fopen into non-sanboxed process. r=mrbkap
dom/base/Navigator.cpp
dom/ipc/ContentChild.cpp
dom/ipc/ContentChild.h
dom/ipc/ContentParent.cpp
dom/ipc/ContentParent.h
dom/ipc/PContent.ipdl
hal/Hal.cpp
hal/Hal.h
hal/fallback/FallbackMemory.cpp
hal/linux/LinuxMemory.cpp
--- a/dom/base/Navigator.cpp
+++ b/dom/base/Navigator.cpp
@@ -93,16 +93,21 @@
 #include "nsIUploadChannel2.h"
 #include "nsFormData.h"
 #include "nsIPrivateBrowsingChannel.h"
 #include "nsIDocShell.h"
 
 #include "WorkerPrivate.h"
 #include "WorkerRunnable.h"
 
+#if defined(XP_LINUX)
+#include "mozilla/Hal.h"
+#endif
+#include "mozilla/dom/ContentChild.h"
+
 namespace mozilla {
 namespace dom {
 
 static bool sDoNotTrackEnabled = false;
 static bool sVibratorEnabled   = false;
 static uint32_t sMaxVibrateMS  = 0;
 static uint32_t sMaxVibrateListLen = 0;
 
@@ -1478,51 +1483,37 @@ Navigator::GetDataStores(const nsAString
 already_AddRefed<Promise>
 Navigator::GetFeature(const nsAString& aName)
 {
   nsCOMPtr<nsIGlobalObject> go = do_QueryInterface(mWindow);
   nsRefPtr<Promise> p = new Promise(go);
 
 #if defined(XP_LINUX)
   if (aName.EqualsLiteral("hardware.memory")) {
-    static int memLevel = 1;
-    if (memLevel == 1) {
-      FILE* f = fopen("/proc/meminfo", "r");
-      if (!f) {
-        p->MaybeReject(NS_LITERAL_STRING("CannotOpenMeminfo"));
-        return p.forget();
-      }
-
-      int memTotal;
-      int n = fscanf(f, "MemTotal: %d kB\n", &memTotal);
-      fclose(f);
-
-      if (memTotal == 0 || n != 1) {
+    // with seccomp enabled, fopen() should be in a non-sandboxed process
+    if (XRE_GetProcessType() == GeckoProcessType_Default) {
+      uint32_t memLevel = mozilla::hal::GetTotalSystemMemoryLevel();
+      if (memLevel == 0) {
         p->MaybeReject(NS_LITERAL_STRING("Abnormal"));
         return p.forget();
       }
-      // From KB to MB
-      memTotal /= 1024;
-
-      // round the value up to the next power of two
-      while (memLevel <= memTotal) {
-        memLevel *= 2;
-      }
+      p->MaybeResolve((int)memLevel);
+    } else {
+      mozilla::dom::ContentChild* cc =
+        mozilla::dom::ContentChild::GetSingleton();
+      nsRefPtr<Promise> ipcRef(p);
+      cc->SendGetSystemMemory(reinterpret_cast<uint64_t>(ipcRef.forget().take()));
     }
-    p->MaybeResolve(memLevel);
+    return p.forget();
   } // hardware.memory
-  else
 #endif
-  {
-    // resolve with <undefined> because the feature name is not supported
-    p->MaybeResolve(JS::UndefinedHandleValue);
-  }
+  // resolve with <undefined> because the feature name is not supported
+  p->MaybeResolve(JS::UndefinedHandleValue);
 
   return p.forget();
-
 }
 
 
 PowerManager*
 Navigator::GetMozPower(ErrorResult& aRv)
 {
   if (!mPowerManager) {
     if (!mWindow) {
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -18,16 +18,17 @@
 #include "TabChild.h"
 
 #include "mozilla/Attributes.h"
 #include "mozilla/dom/asmjscache/AsmJSCache.h"
 #include "mozilla/dom/asmjscache/PAsmJSCacheEntryChild.h"
 #include "mozilla/dom/ExternalHelperAppChild.h"
 #include "mozilla/dom/PCrashReporterChild.h"
 #include "mozilla/dom/DOMStorageIPC.h"
+#include "mozilla/dom/Promise.h"
 #include "mozilla/hal_sandbox/PHalChild.h"
 #include "mozilla/ipc/BackgroundChild.h"
 #include "mozilla/ipc/FileDescriptorUtils.h"
 #include "mozilla/ipc/GeckoChildProcessHost.h"
 #include "mozilla/ipc/TestShellChild.h"
 #include "mozilla/layers/CompositorChild.h"
 #include "mozilla/layers/ImageBridgeChild.h"
 #include "mozilla/layers/SharedBufferManagerChild.h"
@@ -1432,16 +1433,32 @@ nsresult
 ContentChild::AddRemoteAlertObserver(const nsString& aData,
                                      nsIObserver* aObserver)
 {
     NS_ASSERTION(aObserver, "Adding a null observer?");
     mAlertObservers.AppendElement(new AlertObserver(aObserver, aData));
     return NS_OK;
 }
 
+
+bool
+ContentChild::RecvSystemMemoryAvailable(const uint64_t& aGetterId,
+                                        const uint32_t& aMemoryAvailable)
+{
+  nsRefPtr<Promise> p = dont_AddRef(reinterpret_cast<Promise*>(aGetterId));
+
+  if (!aMemoryAvailable) {
+    p->MaybeReject(NS_LITERAL_STRING("Abnormal"));
+    return true;
+  }
+
+  p->MaybeResolve((int)aMemoryAvailable);
+  return true;
+}
+
 bool
 ContentChild::RecvPreferenceUpdate(const PrefSetting& aPref)
 {
     Preferences::SetPreference(aPref);
     return true;
 }
 
 bool
--- a/dom/ipc/ContentChild.h
+++ b/dom/ipc/ContentChild.h
@@ -213,16 +213,19 @@ public:
     virtual bool RecvSetOffline(const bool& offline) MOZ_OVERRIDE;
 
     virtual bool RecvSpeakerManagerNotify() MOZ_OVERRIDE;
 
     virtual bool RecvNotifyVisited(const URIParams& aURI) MOZ_OVERRIDE;
     // auto remove when alertfinished is received.
     nsresult AddRemoteAlertObserver(const nsString& aData, nsIObserver* aObserver);
 
+    virtual bool RecvSystemMemoryAvailable(const uint64_t& aGetterId,
+                                           const uint32_t& aMemoryAvailable) MOZ_OVERRIDE;
+
     virtual bool RecvPreferenceUpdate(const PrefSetting& aPref) MOZ_OVERRIDE;
 
     virtual bool RecvNotifyAlertsObserver(const nsCString& aType,
                                           const nsString& aData) MOZ_OVERRIDE;
 
     virtual bool RecvAsyncMessage(const nsString& aMsg,
                                   const ClonedMessageData& aData,
                                   const InfallibleTArray<CpowEntry>& aCpows,
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -114,16 +114,20 @@
 #include "nsIDocShell.h"
 #include "mozilla/net/NeckoMessageUtils.h"
 #include "gfxPrefs.h"
 
 #if defined(ANDROID) || defined(LINUX)
 #include "nsSystemInfo.h"
 #endif
 
+#if defined(XP_LINUX)
+#include "mozilla/Hal.h"
+#endif
+
 #ifdef ANDROID
 # include "gfxAndroidPlatform.h"
 #endif
 
 #ifdef MOZ_PERMISSIONS
 # include "nsPermissionManager.h"
 #endif
 
@@ -3052,16 +3056,31 @@ ContentParent::RecvGetRandomValues(const
     memcpy(randomValues->Elements(), buf, length);
 
     NS_Free(buf);
 
     return true;
 }
 
 bool
+ContentParent::RecvGetSystemMemory(const uint64_t& aGetterId)
+{
+  uint32_t memoryTotal = 0;
+
+#if defined(XP_LINUX)
+  memoryTotal = mozilla::hal::GetTotalSystemMemoryLevel();
+#endif
+
+  unused << SendSystemMemoryAvailable(aGetterId, memoryTotal);
+
+  return true;
+}
+
+
+bool
 ContentParent::RecvLoadURIExternal(const URIParams& uri)
 {
     nsCOMPtr<nsIExternalProtocolService> extProtService(do_GetService(NS_EXTERNALPROTOCOLSERVICE_CONTRACTID));
     if (!extProtService) {
         return true;
     }
     nsCOMPtr<nsIURI> ourURI = DeserializeURI(uri);
     if (!ourURI) {
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -518,17 +518,17 @@ private:
     virtual bool RecvAudioChannelUnregisterType(const AudioChannel& aChannel,
                                                 const bool& aElementHidden,
                                                 const bool& aWithVideo) MOZ_OVERRIDE;
 
     virtual bool RecvAudioChannelChangedNotification() MOZ_OVERRIDE;
 
     virtual bool RecvAudioChannelChangeDefVolChannel(const int32_t& aChannel,
                                                      const bool& aHidden) MOZ_OVERRIDE;
-
+    virtual bool RecvGetSystemMemory(const uint64_t& getterId) MOZ_OVERRIDE;
     virtual bool RecvBroadcastVolume(const nsString& aVolumeName) MOZ_OVERRIDE;
 
     virtual bool RecvSpeakerManagerGetSpeakerStatus(bool* aValue) MOZ_OVERRIDE;
 
     virtual bool RecvSpeakerManagerForceSpeaker(const bool& aEnable) MOZ_OVERRIDE;
 
     virtual bool RecvSystemMessageHandled() MOZ_OVERRIDE;
 
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -352,16 +352,18 @@ child:
 
     RegisterChrome(ChromePackage[] packages, ResourceMapping[] resources,
                    OverrideMapping[] overrides, nsCString locale);
 
     async SetOffline(bool offline);
 
     async NotifyVisited(URIParams uri);
 
+    async SystemMemoryAvailable(uint64_t getterId, uint32_t memoryAvailable);
+
     PreferenceUpdate(PrefSetting pref);
 
     NotifyAlertsObserver(nsCString topic, nsString data);
 
     GeolocationUpdate(GeoPosition somewhere);
 
     // nsIPermissionManager messages
     AddPermission(Permission permission);
@@ -431,16 +433,18 @@ parent:
 
     PFileSystemRequest(FileSystemParams params);
 
     sync PCrashReporter(NativeThreadId tid, uint32_t processType);
 
     sync GetRandomValues(uint32_t length)
         returns (uint8_t[] randomValues);
 
+    async GetSystemMemory(uint64_t getterId);
+
     PHal();
 
     PIndexedDB();
 
     PNecko();
 
     PSms();
 
--- a/hal/Hal.cpp
+++ b/hal/Hal.cpp
@@ -1227,11 +1227,16 @@ StopDiskSpaceWatcher()
 }
 
 uint32_t
 GetTotalSystemMemory()
 {
   return hal_impl::GetTotalSystemMemory();
 }
 
+uint32_t
+GetTotalSystemMemoryLevel()
+{
+  return hal_impl::GetTotalSystemMemoryLevel();
+}
 
 } // namespace hal
 } // namespace mozilla
--- a/hal/Hal.h
+++ b/hal/Hal.h
@@ -611,16 +611,24 @@ void StopDiskSpaceWatcher();
 
 /**
  * Get total system memory of device being run on in bytes.
  *
  * Returns 0 if we are unable to determine this information from /proc/meminfo.
  */
 uint32_t GetTotalSystemMemory();
 
+/**
+ * Get the level of total system memory on device in MiB.
+ * (round the value up to the next power of two)
+ *
+ * Returns 0 if we are unable to determine this information from /proc/meminfo.
+ */
+uint32_t GetTotalSystemMemoryLevel();
+
 } // namespace MOZ_HAL_NAMESPACE
 } // namespace mozilla
 
 #ifdef MOZ_DEFINED_HAL_NAMESPACE
 # undef MOZ_DEFINED_HAL_NAMESPACE
 # undef MOZ_HAL_NAMESPACE
 #endif
 
--- a/hal/fallback/FallbackMemory.cpp
+++ b/hal/fallback/FallbackMemory.cpp
@@ -11,10 +11,16 @@ namespace mozilla {
 namespace hal_impl {
 
 uint32_t
 GetTotalSystemMemory()
 {
 	return 0;
 }
 
+uint32_t
+GetTotalSystemMemoryLevel()
+{
+	return 0;
+}
+
 } // namespace hal_impl
 } // namespace mozilla
--- a/hal/linux/LinuxMemory.cpp
+++ b/hal/linux/LinuxMemory.cpp
@@ -30,10 +30,42 @@ GetTotalSystemMemory()
     if (fclose(fd) || rv != 1) {
       return 0;
     }
   }
 
   return sTotalMemory * 1024;
 }
 
+uint32_t
+GetTotalSystemMemoryLevel()
+{
+  static uint32_t sTotalMemoryLevel = 1;
+  uint32_t sTotalMemory;
+  static bool sTotalMemoryObtained = false;
+
+  if (!sTotalMemoryObtained) {
+    sTotalMemoryObtained = true;
+
+    FILE* fd = fopen("/proc/meminfo", "r");
+    if (!fd) {
+      return 0;
+    }
+
+    int rv = fscanf(fd, "MemTotal: %i kB", &sTotalMemory);
+
+    if (fclose(fd) || rv != 1) {
+      return 0;
+    }
+
+    // From KB to MiB
+    sTotalMemory /= 1024;
+
+    while (sTotalMemoryLevel <= sTotalMemory) {
+      sTotalMemoryLevel *= 2;
+    }
+  }
+
+  return sTotalMemoryLevel;
+}
+
 } // namespace hal_impl
 } // namespace mozilla