summaryrefslogtreecommitdiffstats
path: root/security/sandbox/common/test/SandboxTestingChild.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'security/sandbox/common/test/SandboxTestingChild.cpp')
-rw-r--r--security/sandbox/common/test/SandboxTestingChild.cpp139
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