fune/security/sandbox/linux/SandboxOpenedFiles.h
Jed Davis 3e1dc3d1eb Bug 1712506 - In the Linux CDM sandbox, don't log when denying access to certain files. r=gcp
The Widevine CDM tries to open certain procfs/sysfs files, as noted
in the bug, but doesn't appear to need them; some of them are opened
repeatedly, causing log spam.  This patch suppresses logging for the
files where this is known to happen, by adding "opened file" objects
that always silently fail.

It would also be possible to turn off all of this logging by default
and make it conditional on MOZ_SANDBOX_LOGGING, but it's relatively
low-noise (compared to content process file access) and provides some
value (see bug 1725828), so for now let's leave it enabled and just
blocklist a few files.

Differential Revision: https://phabricator.services.mozilla.com/D123562
2021-08-26 23:10:30 +00:00

97 lines
3.4 KiB
C++

/* -*- 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