diff options
Diffstat (limited to 'security/sandbox/common/test/SandboxTestingChild.cpp')
-rw-r--r-- | security/sandbox/common/test/SandboxTestingChild.cpp | 139 |
1 files changed, 139 insertions, 0 deletions
diff --git a/security/sandbox/common/test/SandboxTestingChild.cpp b/security/sandbox/common/test/SandboxTestingChild.cpp new file mode 100644 index 0000000000..be68b2ba46 --- /dev/null +++ b/security/sandbox/common/test/SandboxTestingChild.cpp @@ -0,0 +1,139 @@ +/* -*- 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 https://mozilla.org/MPL/2.0/. */ + +#include "SandboxTestingChild.h" +#include "SandboxTestingThread.h" + +#include "nsXULAppAPI.h" + +#ifdef XP_UNIX +# include <fcntl.h> +# include <sys/stat.h> +# include <sys/types.h> +# include <time.h> +# include <unistd.h> +#endif + +namespace mozilla { + +SandboxTestingChild* SandboxTestingChild::sInstance = nullptr; + +bool SandboxTestingChild::IsTestThread() { return mThread->IsOnThread(); } + +void SandboxTestingChild::PostToTestThread( + already_AddRefed<nsIRunnable>&& runnable) { + mThread->Dispatch(std::move(runnable)); +} + +/* static */ +bool SandboxTestingChild::Initialize( + Endpoint<PSandboxTestingChild>&& aSandboxTestingEndpoint) { + MOZ_ASSERT(!sInstance); + SandboxTestingThread* thread = SandboxTestingThread::Create(); + if (!thread) { + return false; + } + sInstance = + new SandboxTestingChild(thread, std::move(aSandboxTestingEndpoint)); + return true; +} + +/* static */ +SandboxTestingChild* SandboxTestingChild::GetInstance() { + MOZ_ASSERT(sInstance, "Must initialize SandboxTestingChild before using it"); + return sInstance; +} + +SandboxTestingChild::SandboxTestingChild( + SandboxTestingThread* aThread, Endpoint<PSandboxTestingChild>&& aEndpoint) + : mThread(aThread) { + MOZ_ASSERT(aThread); + PostToTestThread(NewNonOwningRunnableMethod<Endpoint<PSandboxTestingChild>&&>( + "SandboxTestingChild::Bind", this, &SandboxTestingChild::Bind, + std::move(aEndpoint))); +} + +void SandboxTestingChild::Bind(Endpoint<PSandboxTestingChild>&& aEndpoint) { + MOZ_RELEASE_ASSERT(mThread->IsOnThread()); + DebugOnly<bool> ok = aEndpoint.Bind(this); + MOZ_ASSERT(ok); + + if (XRE_IsContentProcess()) { +#ifdef XP_UNIX + struct stat st; + static const char kAllowedPath[] = "/usr/lib"; + + ErrnoTest("fstatat_as_stat"_ns, true, + [&] { return fstatat(AT_FDCWD, kAllowedPath, &st, 0); }); + ErrnoTest("fstatat_as_lstat"_ns, true, [&] { + return fstatat(AT_FDCWD, kAllowedPath, &st, AT_SYMLINK_NOFOLLOW); + }); + +# ifdef XP_LINUX + ErrnoTest("fstatat_as_fstat"_ns, true, + [&] { return fstatat(0, "", &st, AT_EMPTY_PATH); }); +# endif // XP_LINUX + + const struct timespec usec = {0, 1000}; + ErrnoTest("nanosleep"_ns, true, [&] { return nanosleep(&usec, nullptr); }); + + struct timespec res = {0, 0}; + ErrnoTest("clock_getres"_ns, true, + [&] { return clock_getres(CLOCK_REALTIME, &res); }); + +#else // XP_UNIX + SendReportTestResults("dummy_test"_ns, + /* shouldSucceed */ true, + /* didSucceed */ true, + "The test framework fails if there are no cases."_ns); +#endif // XP_UNIX + } + + // Tell SandboxTest that this process is done with all tests. + SendTestCompleted(); +} + +void SandboxTestingChild::ActorDestroy(ActorDestroyReason aWhy) { + MOZ_ASSERT(mThread->IsOnThread()); + NS_DispatchToMainThread(NS_NewRunnableFunction( + "SandboxChildDestroyer", []() { SandboxTestingChild::Destroy(); })); +} + +void SandboxTestingChild::Destroy() { + MOZ_ASSERT(NS_IsMainThread()); + MOZ_ASSERT(sInstance); + delete sInstance; + sInstance = nullptr; +} + +bool SandboxTestingChild::RecvShutDown() { + Close(); + return true; +} + +#ifdef XP_UNIX +template <typename F> +void SandboxTestingChild::ErrnoTest(const nsCString& aName, bool aExpectSuccess, + F&& aFunction) { + int status = aFunction() >= 0 ? 0 : errno; + PosixTest(aName, aExpectSuccess, status); +} + +void SandboxTestingChild::PosixTest(const nsCString& aName, bool aExpectSuccess, + int aStatus) { + bool succeeded = aStatus == 0; + nsAutoCString message; + if (succeeded) { + message = "Succeeded"_ns; + } else { + message.AppendPrintf("Error: %s", strerror(aStatus)); + } + + SendReportTestResults(aName, aExpectSuccess, succeeded, message); +} +#endif // XP_UNIX + +} // namespace mozilla |