Commit ac85827e authored by Jed Davis's avatar Jed Davis
Browse files

Bug 1698778 - Allow filtering SysV IPC call arguments. r=gcp

On 32-bit x86, Linux originally used a single system call, ipc(2), for
all SysV IPC.  This is similar to socketcall(2), but the arguments are
passed directly (shifted by one position) instead of indirected via
a pointer, so seccomp-bpf can filter them normally.  Also similar to
socketcall(2), individual syscalls were added later (in kernel 5.1,
vs. 4.3 for socket calls), so the policy needs to handle both of them,
adjusting argument offsets as needed.  This patch adds an argument to
`EvaluateIpcCall` to allow that.

Differential Revision: https://phabricator.services.mozilla.com/D131678
parent 49842aaa
Loading
Loading
Loading
Loading
+3 −3
Original line number Diff line number Diff line
@@ -1199,7 +1199,7 @@ class ContentSandboxPolicy : public SandboxPolicyCommon {
  }

#ifdef DESKTOP
  Maybe<ResultExpr> EvaluateIpcCall(int aCall) const override {
  Maybe<ResultExpr> EvaluateIpcCall(int aCall, int aArgShift) const override {
    switch (aCall) {
        // These are a problem: SysV IPC follows the Unix "same uid
        // policy" and can't be restricted/brokered like file access.
@@ -1219,9 +1219,9 @@ class ContentSandboxPolicy : public SandboxPolicyCommon {
        if (mAllowSysV) {
          return Some(Allow());
        }
        return SandboxPolicyCommon::EvaluateIpcCall(aCall);
        return SandboxPolicyCommon::EvaluateIpcCall(aCall, aArgShift);
      default:
        return SandboxPolicyCommon::EvaluateIpcCall(aCall);
        return SandboxPolicyCommon::EvaluateIpcCall(aCall, aArgShift);
    }
  }
#endif
+2 −2
Original line number Diff line number Diff line
@@ -56,7 +56,7 @@ sandbox::bpf_dsl::ResultExpr SandboxPolicyBase::EvaluateSyscall(
      auto call = callAndVersion & 0xFFFF;
      UniquePtr<Caser<int>> acc(new Caser<int>(Switch(call)));
      for (int i = SEMOP; i <= DIPC; ++i) {
        auto thisCase = EvaluateIpcCall(i);
        auto thisCase = EvaluateIpcCall(i, 1);
        // Optimize out cases that are equal to the default.
        if (thisCase) {
          acc.reset(new Caser<int>(acc->Case(i, *thisCase)));
@@ -99,7 +99,7 @@ sandbox::bpf_dsl::ResultExpr SandboxPolicyBase::EvaluateSyscall(
#ifndef ANDROID
#define DISPATCH_SYSVCALL(sysnum, ipcnum) \
  case sysnum:                            \
    return EvaluateIpcCall(ipcnum).valueOr(InvalidSyscall())
    return EvaluateIpcCall(ipcnum, 0).valueOr(InvalidSyscall())
      DISPATCH_SYSVCALL(__NR_semop,       SEMOP);
      DISPATCH_SYSVCALL(__NR_semget,      SEMGET);
      DISPATCH_SYSVCALL(__NR_semctl,      SEMCTL);
+5 −2
Original line number Diff line number Diff line
@@ -42,10 +42,13 @@ class SandboxPolicyBase : public sandbox::bpf_dsl::Policy {
    return Nothing();
  }

#ifndef ANDROID
  // Android doesn't use SysV IPC (and doesn't define the selector
  // constants in its headers), so this isn't implemented there.
  virtual Maybe<ResultExpr> EvaluateIpcCall(int aCall) const {
#ifndef ANDROID
  // aArgShift is the offset to add the argument index when
  // constructing `Arg` objects: it's 0 for separate syscalls and 1
  // for ipc().
  virtual Maybe<ResultExpr> EvaluateIpcCall(int aCall, int aArgShift) const {
    return Nothing();
  }
#endif