Bug 996996 - Move fopen into non-sanboxed process. r=mrbkap
authorAlphan Chen<alchen@mozilla.com>
Wed, 21 May 2014 13:49:36 +0800
changeset 184067 afe8ef1b62d138cf3c13833be8c0d7d4cd132d7e
parent 184066 5a562c4ceb494f20d15e7c698b9ca7430ccd7966
child 184068 b34ba09e0391f1cbff3b3255e09d898978214ec5
push id26810
push usercbook@mozilla.com
push dateWed, 21 May 2014 11:46:36 +0000
treeherdermozilla-central@50fb8c4db2fd [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmrbkap
bugs996996
milestone32.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
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