summaryrefslogtreecommitdiffstats
path: root/security/sandbox/linux/SandboxOpenedFiles.h
diff options
context:
space:
mode:
Diffstat (limited to 'security/sandbox/linux/SandboxOpenedFiles.h')
-rw-r--r--security/sandbox/linux/SandboxOpenedFiles.h97
1 files changed, 97 insertions, 0 deletions
diff --git a/security/sandbox/linux/SandboxOpenedFiles.h b/security/sandbox/linux/SandboxOpenedFiles.h
new file mode 100644
index 0000000000..24881b93f0
--- /dev/null
+++ b/security/sandbox/linux/SandboxOpenedFiles.h
@@ -0,0 +1,97 @@
+/* -*- 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/. */
+
+#ifndef mozilla_SandboxOpenedFiles_h
+#define mozilla_SandboxOpenedFiles_h
+
+#include "mozilla/Atomics.h"
+#include "mozilla/Range.h"
+#include "mozilla/UniquePtr.h"
+
+#include <vector>
+#include <string>
+
+// The use of C++ standard library containers here should be safe; the
+// standard (section container.requirements.dataraces) requires that
+// using const methods/pointers not introduce data races (e.g., from
+// interior mutability or global state).
+//
+// Reentrancy isn't guaranteed, and the library could use async signal
+// unsafe mutexes for "read-only" operations, but I'm assuming that that's
+// not the case at least for simple containers like string and vector.
+
+namespace mozilla {
+
+// This class represents a file that's been pre-opened for a media
+// plugin. It can be move-constructed but not copied.
+class SandboxOpenedFile final {
+ public:
+ enum class Dup { NO, YES };
+ struct Error {};
+
+ // This constructor opens the named file and saves the descriptor.
+ // If the open fails, IsOpen() will return false and GetDesc() will
+ // quietly return -1. If aDup is Dup::YES, GetDesc() will return a
+ // dup() of the descriptor every time it's called; otherwise, the
+ // first call will return the descriptor and any further calls will
+ // log an error message and return -1.
+ explicit SandboxOpenedFile(const char* aPath, Dup aDup = Dup::NO);
+
+ // This constructor is for files which the process will try to open
+ // but we don't want to grant access: using it will always fail
+ // (GetDesc will return -1) without logging.
+ SandboxOpenedFile(const char* aPath, Error);
+
+ // Simulates opening the pre-opened file; see the constructor's
+ // comment for details. Does not set errno on error, but may modify
+ // it as a side-effect. Thread-safe and intended to be async signal safe.
+ int GetDesc() const;
+
+ const char* Path() const { return mPath.c_str(); }
+
+ bool IsOpen() const { return mMaybeFd >= 0; }
+
+ ~SandboxOpenedFile();
+
+ MOZ_IMPLICIT SandboxOpenedFile(SandboxOpenedFile&& aMoved);
+
+ private:
+ std::string mPath;
+ mutable Atomic<int> mMaybeFd;
+ bool mDup;
+ bool mExpectError;
+
+ int TakeDesc() const { return mMaybeFd.exchange(-1); }
+};
+
+// This class represents a collection of files to be used to handle
+// open() calls from the media plugin (and the dynamic loader).
+// Because the seccomp-bpf policy exists until the process exits, this
+// object must not be destroyed after the syscall filter is installed.
+class SandboxOpenedFiles {
+ public:
+ SandboxOpenedFiles() = default;
+
+ template <typename... Args>
+ void Add(Args&&... aArgs) {
+ mFiles.emplace_back(std::forward<Args>(aArgs)...);
+ }
+
+ int GetDesc(const char* aPath) const;
+
+ private:
+ std::vector<SandboxOpenedFile> mFiles;
+
+ // We could allow destroying instances of this class that aren't
+ // used with seccomp-bpf (e.g., for unit testing) by having the
+ // destructor check a flag set by the syscall policy and crash,
+ // but let's not write that code until we actually need it.
+ ~SandboxOpenedFiles() = delete;
+};
+
+} // namespace mozilla
+
+#endif // mozilla_SandboxOpenedFiles_h