/* -*- 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/. */
// 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 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, // Applies to everything below this path, including subdirs created // at runtime
RECURSIVE = 1 << 5, // Allow Unix-domain socket connections to a path
MAY_CONNECT = 1 << 6, // This flag is for adding a deny rule, so that we can e.g., allow read // access to ~/.config/ but still deny access to ~/.config/mozilla/. // It will bypass other checks.
FORCE_DENY = 1 << 7,
}; // 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 nsTHashMap<nsCStringHashKey, int> PathPermissionMap;
// Add permissions from AddTree/AddDynamic rules to any rules that // exist for their descendents, and remove any descendent rules // made redundant by this process. // // Call this after adding rules and before using the policy to // prevent the descendent rules from shadowing the ancestor rules // and removing permissions that we expect the file to have. void FixRecursivePermissions();
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, constchar* aPath, AddCondition aCond); // A directory, and all files and directories under it, even those // added after creation (the dir itself must exist). void AddTree(int aPerms, constchar* aPath); // A directory, and all files and directories under it, even those // added after creation (the dir itself may not exist). void AddFutureDir(int aPerms, constchar* aPath); // All files in a directory with a given prefix; useful for devices. void AddFilePrefix(int aPerms, constchar* aDir, constchar* aPrefix); // Everything starting with the given path, even those files/dirs // added after creation. The file or directory may or may not exist. void AddPrefix(int aPerms, constchar* aPath); // Adds a file or dir (end with /) if it exists, and a prefix otherwhise. void AddDynamic(int aPerms, constchar* aPath); // Adds permissions on all ancestors of a path. (This doesn't // include the root directory, but if the path is given with a // trailing slash it includes the path without the slash.) void AddAncestors(constchar* aPath, int aPerms = MAY_ACCESS); // 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, constchar* aPath) {
AddPath(aPerms, aPath,
(aPerms & MAY_CREATE) ? AddAlways : AddIfExistsNow);
} int Lookup(const nsACString& aPath) const; int Lookup(constchar* aPath) const { return Lookup(nsDependentCString(aPath));
}
private: // ValidatePath checks |path| and returns true if these conditions are met // * Greater than 0 length // * Is an absolute path // * No trailing slash // * No /../ path traversal bool ValidatePath(constchar* path) const; void AddPrefixInternal(int aPerms, const nsACString& aPath); void AddTreeInternal(int aPerms, constchar* 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();
SandboxBroker(UniquePtr<const Policy> aPolicy, int aChildPid, int& aClientFd); void ThreadMain(void) override; void AuditPermissive(int aOp, int aFlags, uint64_t aId, int aPerms, constchar* aPath); void AuditDenial(int aOp, int aFlags, uint64_t aId, int aPerms, constchar* aPath); // Remap relative paths to absolute paths.
size_t ConvertRelativePath(char* aPath, size_t aBufSize, size_t aPathLen);
size_t RealPath(char* aPath, size_t aBufSize, size_t aPathLen);
nsCString ReverseSymlinks(const nsACString& aPath); // Retrieves permissions for the path the original symlink sits in. int SymlinkPermissions(constchar* aPath, const size_t aPathLen); // In SandboxBrokerRealPath.cpp char* SymlinkPath(const Policy* aPolicy, constchar* __restrict aPath, char* __restrict aResolved, int* aPermission);
// Holding a UniquePtr should disallow copying, but to make that explicit:
SandboxBroker(const SandboxBroker&) = delete; voidoperator=(const SandboxBroker&) = delete;
};
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.