Bug 996996 - Move fopen into non-sanboxed process. r=mrbkap

This commit is contained in:
Alphan Chen 2014-05-21 13:49:36 +08:00
parent f89c614a21
commit 7082834baf
10 changed files with 113 additions and 28 deletions

View File

@ -98,6 +98,11 @@
#include "WorkerPrivate.h"
#include "WorkerRunnable.h"
#if defined(XP_LINUX)
#include "mozilla/Hal.h"
#endif
#include "mozilla/dom/ContentChild.h"
namespace mozilla {
namespace dom {
@ -1483,41 +1488,27 @@ Navigator::GetFeature(const nsAString& aName)
#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();
}

View File

@ -23,6 +23,7 @@
#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"
@ -1437,6 +1438,22 @@ ContentChild::AddRemoteAlertObserver(const nsString& 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)
{

View File

@ -218,6 +218,9 @@ public:
// 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,

View File

@ -119,6 +119,10 @@
#include "nsSystemInfo.h"
#endif
#if defined(XP_LINUX)
#include "mozilla/Hal.h"
#endif
#ifdef ANDROID
# include "gfxAndroidPlatform.h"
#endif
@ -3056,6 +3060,21 @@ ContentParent::RecvGetRandomValues(const uint32_t& length,
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)
{

View File

@ -523,7 +523,7 @@ private:
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;

View File

@ -357,6 +357,8 @@ child:
async NotifyVisited(URIParams uri);
async SystemMemoryAvailable(uint64_t getterId, uint32_t memoryAvailable);
PreferenceUpdate(PrefSetting pref);
NotifyAlertsObserver(nsCString topic, nsString data);
@ -436,6 +438,8 @@ parent:
sync GetRandomValues(uint32_t length)
returns (uint8_t[] randomValues);
async GetSystemMemory(uint64_t getterId);
PHal();
PIndexedDB();

View File

@ -1232,6 +1232,11 @@ GetTotalSystemMemory()
return hal_impl::GetTotalSystemMemory();
}
uint32_t
GetTotalSystemMemoryLevel()
{
return hal_impl::GetTotalSystemMemoryLevel();
}
} // namespace hal
} // namespace mozilla

View File

@ -616,6 +616,14 @@ void StopDiskSpaceWatcher();
*/
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

View File

@ -16,5 +16,11 @@ GetTotalSystemMemory()
return 0;
}
uint32_t
GetTotalSystemMemoryLevel()
{
return 0;
}
} // namespace hal_impl
} // namespace mozilla

View File

@ -35,5 +35,37 @@ GetTotalSystemMemory()
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