зеркало из https://github.com/mozilla/gecko-dev.git
125 строки
4.4 KiB
C++
125 строки
4.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_SandboxBroker_h
|
|
#define mozilla_SandboxBroker_h
|
|
|
|
#include "mozilla/SandboxBrokerCommon.h"
|
|
|
|
#include "base/platform_thread.h"
|
|
#include "mozilla/Attributes.h"
|
|
#include "mozilla/UniquePtr.h"
|
|
#include "nsDataHashtable.h"
|
|
#include "nsHashKeys.h"
|
|
#include "nsString.h"
|
|
|
|
namespace mozilla {
|
|
|
|
namespace ipc {
|
|
class FileDescriptor;
|
|
}
|
|
|
|
// This class implements a broker for filesystem operations requested
|
|
// by a sandboxed child process -- opening files and accessing their
|
|
// metadata. (This is necessary in order to restrict access by path;
|
|
// seccomp-bpf can filter only on argument register values, not
|
|
// parameters passed in memory like pathnames.)
|
|
//
|
|
// The policy is currently just a map from strings to sets of
|
|
// permissions; the broker doesn't attempt to interpret or
|
|
// canonicalize pathnames. This makes the broker simpler, and thus
|
|
// less likely to contain vulnerabilities a compromised client could
|
|
// exploit. (This might need to change in the future if we need to
|
|
// whitelist a set of files that could change after policy
|
|
// construction, like hotpluggable devices.)
|
|
//
|
|
// The broker currently runs on a thread in the parent process (with
|
|
// effective uid changed on B2G), which is for memory efficiency
|
|
// (compared to forking a process) and simplicity (compared to having
|
|
// a separate executable and serializing/deserializing the policy).
|
|
//
|
|
// See also ../SandboxBrokerClient.h for the corresponding client.
|
|
|
|
class SandboxBroker final
|
|
: private SandboxBrokerCommon
|
|
, public PlatformThread::Delegate
|
|
{
|
|
public:
|
|
enum Perms {
|
|
MAY_ACCESS = 1 << 0,
|
|
MAY_READ = 1 << 1,
|
|
MAY_WRITE = 1 << 2,
|
|
MAY_CREATE = 1 << 3,
|
|
// This flag is for testing policy changes -- when the client is
|
|
// used with the seccomp-bpf integration, an access to this file
|
|
// will invoke a crash dump with the context of the syscall.
|
|
// (This overrides all other flags.)
|
|
CRASH_INSTEAD = 1 << 4,
|
|
};
|
|
// Bitwise operations on enum values return ints, so just use int in
|
|
// the hash table type (and below) to avoid cluttering code with casts.
|
|
typedef nsDataHashtable<nsCStringHashKey, int> PathMap;
|
|
|
|
class Policy {
|
|
PathMap mMap;
|
|
public:
|
|
Policy();
|
|
Policy(const Policy& aOther);
|
|
~Policy();
|
|
|
|
enum AddCondition {
|
|
AddIfExistsNow,
|
|
AddAlways,
|
|
};
|
|
// Typically, files that don't exist at policy creation time don't
|
|
// need to be whitelisted, but this allows adding entries for
|
|
// them if they'll exist later. See also the overload below.
|
|
void AddPath(int aPerms, const char* aPath, AddCondition aCond);
|
|
// This adds all regular files (not directories) in the tree
|
|
// rooted at the given path.
|
|
void AddTree(int aPerms, const char* aPath);
|
|
// All files in a directory with a given prefix; useful for devices.
|
|
void AddPrefix(int aPerms, const char* aDir, const char* aPrefix);
|
|
// Default: add file if it exists when creating policy or if we're
|
|
// conferring permission to create it (log files, etc.).
|
|
void AddPath(int aPerms, const char* aPath) {
|
|
AddPath(aPerms, aPath,
|
|
(aPerms & MAY_CREATE) ? AddAlways : AddIfExistsNow);
|
|
}
|
|
int Lookup(const nsACString& aPath) const;
|
|
int Lookup(const char* aPath) const {
|
|
return Lookup(nsDependentCString(aPath));
|
|
}
|
|
};
|
|
|
|
// Constructing a broker involves creating a socketpair and a
|
|
// background thread to handle requests, so it can fail. If this
|
|
// returns nullptr, do not use the value of aClientFdOut.
|
|
static UniquePtr<SandboxBroker>
|
|
Create(UniquePtr<const Policy> aPolicy, int aChildPid,
|
|
ipc::FileDescriptor& aClientFdOut);
|
|
virtual ~SandboxBroker();
|
|
|
|
private:
|
|
PlatformThreadHandle mThread;
|
|
int mFileDesc;
|
|
const int mChildPid;
|
|
const UniquePtr<const Policy> mPolicy;
|
|
|
|
SandboxBroker(UniquePtr<const Policy> aPolicy, int aChildPid,
|
|
int& aClientFd);
|
|
void ThreadMain(void) override;
|
|
void AuditDenial(int aOp, int aFlags, const char* aPath);
|
|
|
|
// Holding a UniquePtr should disallow copying, but to make that explicit:
|
|
SandboxBroker(const SandboxBroker&) = delete;
|
|
void operator=(const SandboxBroker&) = delete;
|
|
};
|
|
|
|
} // namespace mozilla
|
|
|
|
#endif // mozilla_SandboxBroker_h
|