зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1740624 - Add RLBox sandbox pool support r=bholley
Differential Revision: https://phabricator.services.mozilla.com/D130934
This commit is contained in:
Родитель
9b61a81283
Коммит
94453a2008
|
@ -0,0 +1,100 @@
|
|||
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef SECURITY_RLBOX_SANDBOX_POOL_H_
|
||||
#define SECURITY_RLBOX_SANDBOX_POOL_H_
|
||||
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsITimer.h"
|
||||
#include "nsTArray.h"
|
||||
|
||||
#include "mozilla/Mutex.h"
|
||||
#include "mozilla/rlbox/rlbox_types.hpp"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
class RLBoxSandboxDataBase;
|
||||
class RLBoxSandboxPoolData;
|
||||
|
||||
// The RLBoxSandboxPool class is used to manage a pool of sandboxes that are
|
||||
// reused -- to save sandbox creation time and memory -- and automatically
|
||||
// destroyed when no longer in used. The sandbox pool is threadsafe and can be
|
||||
// used to share unused sandboxes across a thread pool.
|
||||
//
|
||||
// Each sandbox pool manages a particular kind of sandbox (e.g., expat
|
||||
// sandboxes, woff2 sandboxes, etc.); this is largely because different
|
||||
// sandboxes might have different callbacks and attacker assumptions. Hence,
|
||||
// RLBoxSandboxPool is intended to be subclassed for the different kinds of
|
||||
// sandbox pools. Each sandbox pool class needs to implement the
|
||||
// CreateSandboxData() method, which returns a pointer to a RLBoxSandboxDataBase
|
||||
// object. RLBoxSandboxDataBase itself should be subclassed to implement
|
||||
// sandbox-specific details.
|
||||
class RLBoxSandboxPool : public nsITimerCallback, public nsINamed {
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSITIMERCALLBACK
|
||||
NS_DECL_NSINAMED
|
||||
|
||||
RLBoxSandboxPool(size_t aDelaySeconds = 10)
|
||||
: mPool(),
|
||||
mDelaySeconds(aDelaySeconds),
|
||||
mMutex("RLBoxSandboxPool::mMutex"){};
|
||||
|
||||
void Push(UniquePtr<RLBoxSandboxDataBase> sbx);
|
||||
// PopOrCreate() returns a sandbox from the pool if the pool is not empty and
|
||||
// tries to mint a new one otherwise. If creating a new sandbox fails, the
|
||||
// function returns a nullptr.
|
||||
UniquePtr<RLBoxSandboxPoolData> PopOrCreate();
|
||||
|
||||
protected:
|
||||
virtual UniquePtr<RLBoxSandboxDataBase> CreateSandboxData() = 0;
|
||||
virtual ~RLBoxSandboxPool() = default;
|
||||
|
||||
private:
|
||||
void StartTimer();
|
||||
void CancelTimer();
|
||||
|
||||
nsTArray<UniquePtr<RLBoxSandboxDataBase>> mPool;
|
||||
const size_t mDelaySeconds;
|
||||
nsCOMPtr<nsITimer> mTimer;
|
||||
mozilla::Mutex mMutex;
|
||||
};
|
||||
|
||||
// The RLBoxSandboxDataBase class serves as the subclass for all sandbox data
|
||||
// classes, which keep track of the RLBox sandbox and any relevant sandbox data
|
||||
// (e.g., callbacks).
|
||||
class RLBoxSandboxDataBase {
|
||||
public:
|
||||
virtual ~RLBoxSandboxDataBase() = default;
|
||||
};
|
||||
|
||||
// This class is used wrap sandbox data objects (RLBoxSandboxDataBase) when they
|
||||
// are popped from sandbox pools. The wrapper destructor pushes the sandbox back
|
||||
// into the pool.
|
||||
class RLBoxSandboxPoolData {
|
||||
public:
|
||||
RLBoxSandboxPoolData(UniquePtr<RLBoxSandboxDataBase> aSbxData,
|
||||
RefPtr<RLBoxSandboxPool> aPool) {
|
||||
mSbxData = std::move(aSbxData);
|
||||
mPool = aPool;
|
||||
MOZ_COUNT_CTOR(RLBoxSandboxPoolData);
|
||||
}
|
||||
|
||||
const RLBoxSandboxDataBase* SandboxData() const { return mSbxData.get(); };
|
||||
|
||||
~RLBoxSandboxPoolData() {
|
||||
mPool->Push(std::move(mSbxData));
|
||||
MOZ_COUNT_DTOR(RLBoxSandboxPoolData);
|
||||
};
|
||||
|
||||
private:
|
||||
UniquePtr<RLBoxSandboxDataBase> mSbxData;
|
||||
RefPtr<RLBoxSandboxPool> mPool;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif
|
|
@ -10,10 +10,17 @@ WASM_SOURCES += [
|
|||
|
||||
LOCAL_INCLUDES += ["/third_party/wasm2c/wasm2c/"]
|
||||
|
||||
EXPORTS += ["/third_party/wasm2c/wasm2c/wasm-rt.h"]
|
||||
EXPORTS += [
|
||||
"/third_party/wasm2c/wasm2c/wasm-rt.h",
|
||||
]
|
||||
|
||||
EXPORTS.mozilla += [
|
||||
"/security/rlbox/include/RLBoxSandboxPool.h",
|
||||
]
|
||||
|
||||
SOURCES += [
|
||||
"!rlbox.wasm.c",
|
||||
"/security/rlbox/src/RLBoxSandboxPool.cpp",
|
||||
"/third_party/wasm2c/wasm2c/wasm-rt-impl.c",
|
||||
"/third_party/wasm2c/wasm2c/wasm-rt-os-unix.c",
|
||||
"/third_party/wasm2c/wasm2c/wasm-rt-os-win.c",
|
||||
|
|
|
@ -0,0 +1,71 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsThreadUtils.h"
|
||||
#include "mozilla/DebugOnly.h"
|
||||
#include "mozilla/RLBoxSandboxPool.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
NS_IMPL_ISUPPORTS(RLBoxSandboxPool, nsITimerCallback, nsINamed)
|
||||
|
||||
void RLBoxSandboxPool::StartTimer() {
|
||||
mMutex.AssertCurrentThreadOwns();
|
||||
MOZ_ASSERT(!mTimer, "timer already initialized");
|
||||
DebugOnly<nsresult> rv = NS_NewTimerWithCallback(
|
||||
getter_AddRefs(mTimer), this, mDelaySeconds * 1000,
|
||||
nsITimer::TYPE_ONE_SHOT, GetMainThreadEventTarget());
|
||||
MOZ_ASSERT(NS_SUCCEEDED(rv), "failed to create timer");
|
||||
}
|
||||
|
||||
void RLBoxSandboxPool::CancelTimer() {
|
||||
mMutex.AssertCurrentThreadOwns();
|
||||
if (mTimer) {
|
||||
mTimer->Cancel();
|
||||
mTimer = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP RLBoxSandboxPool::Notify(nsITimer* aTimer) {
|
||||
MutexAutoLock lock(mMutex);
|
||||
|
||||
mPool.Clear();
|
||||
mTimer = nullptr;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP RLBoxSandboxPool::GetName(nsACString& aName) {
|
||||
aName.AssignLiteral("RLBoxSandboxPool");
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void RLBoxSandboxPool::Push(UniquePtr<RLBoxSandboxDataBase> sbxData) {
|
||||
MutexAutoLock lock(mMutex);
|
||||
|
||||
mPool.AppendElement(std::move(sbxData));
|
||||
if (!mTimer) {
|
||||
StartTimer();
|
||||
}
|
||||
}
|
||||
|
||||
UniquePtr<RLBoxSandboxPoolData> RLBoxSandboxPool::PopOrCreate() {
|
||||
MutexAutoLock lock(mMutex);
|
||||
|
||||
UniquePtr<RLBoxSandboxDataBase> sbxData;
|
||||
if (!mPool.IsEmpty()) {
|
||||
sbxData = mPool.PopLastElement();
|
||||
CancelTimer();
|
||||
if (!mPool.IsEmpty()) {
|
||||
StartTimer();
|
||||
}
|
||||
} else {
|
||||
sbxData = CreateSandboxData();
|
||||
NS_ENSURE_TRUE(sbxData, nullptr);
|
||||
}
|
||||
|
||||
return MakeUnique<RLBoxSandboxPoolData>(std::move(sbxData), this);
|
||||
}
|
Загрузка…
Ссылка в новой задаче