gecko/security/sandbox/linux/SandboxAssembler.h
Jed Davis 5748fc5814 Bug 1102209 - Remove use of CodeGen::JoinInstructions in the Linux sandboxing code. r=kang
This reorganizes SandboxAssembler to stack up the policy rules and
traverse them in reverse order to build the filter DAG from tail to head
(i.e., starting with "deny all" and prepending allow and return-errno
rules).  Thus, this code will continue to work (perhaps with minor
changes, such as to the NodePtr typedef) with future versions of the
Chromium sandbox code that don't allow mutating the filter program with
the JoinInstructions method.
2014-12-10 17:26:12 -08:00

78 lines
2.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_SandboxAssembler_h
#define mozilla_SandboxAssembler_h
#include <vector>
#include "mozilla/Assertions.h"
struct sock_filter;
namespace mozilla {
class SandboxAssembler {
public:
class Condition {
friend class SandboxAssembler;
uint32_t mSyscallNr;
bool mCheckingArg;
uint8_t mArgChecked;
// This class retains a copy of the array, because C++11
// initializer_list isn't supported on all relevant platforms.
std::vector<uint32_t> mArgValues;
public:
// Match any instance of the given syscall, with any arguments.
explicit Condition(uint32_t aSyscallNr)
: mSyscallNr(aSyscallNr)
, mCheckingArg(false)
{ }
// Match the syscall only if the given argument is one of the
// values in the array specified. (If the argument isn't
// representable as uint32, the process is killed or signaled, as
// appropriate.)
template<size_t n>
Condition(uint32_t aSyscallNr, uint8_t aArgChecked,
const uint32_t (&aArgValues)[n])
: mSyscallNr(aSyscallNr)
, mCheckingArg(true)
, mArgChecked(aArgChecked)
, mArgValues(aArgValues, aArgValues + n)
{
MOZ_ASSERT(aArgChecked < sNumArgs);
}
// This isn't perf-critical, so a naive copy ctor is fine.
Condition(const Condition& aOther)
: mSyscallNr(aOther.mSyscallNr)
, mCheckingArg(aOther.mCheckingArg)
, mArgChecked(aOther.mArgChecked)
, mArgValues(aOther.mArgValues)
{ }
};
// Allow syscalls matching this condition, if no earlier condition matched.
void Allow(const Condition& aCond) {
mRuleStack.push_back(std::make_pair(0, aCond));
}
// Cause syscalls matching this condition to fail with the given error, if
// no earlier condition matched.
void Deny(int aErrno, const Condition& aCond) {
MOZ_ASSERT(aErrno != 0);
mRuleStack.push_back(std::make_pair(aErrno, aCond));
}
void Compile(std::vector<sock_filter>* aProgram, bool aPrint = false);
private:
std::vector<std::pair<int, Condition>> mRuleStack;
static const uint8_t sNumArgs = 6;
};
}
#endif