Exemplo n.º 1
0
    virtual ResultExpr ClonePolicy() const {
        // Allow use for simple thread creation (pthread_create) only.

        // WARNING: s390 and cris pass the flags in the second arg -- see
        // CLONE_BACKWARDS2 in arch/Kconfig in the kernel source -- but we
        // don't support seccomp-bpf on those archs yet.
        Arg<int> flags(0);

        // The glibc source hasn't changed the thread creation clone flags
        // since 2004, so this *should* be safe to hard-code.  Bionic's
        // value has changed a few times, and has converged on the same one
        // as glibc; allow any of them.
        static const int flags_common = CLONE_VM | CLONE_FS | CLONE_FILES |
                                        CLONE_SIGHAND | CLONE_THREAD | CLONE_SYSVSEM;
        static const int flags_modern = flags_common | CLONE_SETTLS |
                                        CLONE_PARENT_SETTID | CLONE_CHILD_CLEARTID;

        // Can't use CASES here because its decltype magic infers const
        // int instead of regular int and bizarre voluminous errors issue
        // forth from the depths of the standard library implementation.
        return Switch(flags)
#ifdef ANDROID
               .Case(flags_common | CLONE_DETACHED, Allow()) // <= JB 4.2
               .Case(flags_common, Allow()) // JB 4.3 or KK 4.4
#endif
               .Case(flags_modern, Allow()) // Android L or glibc
               .Default(InvalidSyscall());
    }
Exemplo n.º 2
0
 virtual ResultExpr PrctlPolicy() const {
     // Note: this will probably need PR_SET_VMA if/when it's used on
     // Android without being overridden by an allow-all policy, and
     // the constant will need to be defined locally.
     Arg<int> op(0);
     return Switch(op)
            .CASES((PR_GET_SECCOMP, // BroadcastSetThreadSandbox, etc.
                    PR_SET_NAME,    // Thread creation
                    PR_SET_DUMPABLE), // Crash reporting
                   Allow())
            .Default(InvalidSyscall());
 }
Exemplo n.º 3
0
    virtual ResultExpr EvaluateSyscall(int sysno) const override {
        switch (sysno) {
            // Simulate opening the plugin file.
#ifdef __NR_open
        case __NR_open:
#endif
        case __NR_openat:
            return Trap(OpenTrap, mPlugin);

        // ipc::Shmem
        case __NR_mprotect:
            return Allow();
        case __NR_madvise: {
            Arg<int> advice(2);
            return If(advice == MADV_DONTNEED, Allow())
                   .Else(InvalidSyscall());
        }

        default:
            return SandboxPolicyCommon::EvaluateSyscall(sysno);
        }
    }
Exemplo n.º 4
0
    virtual Maybe<ResultExpr> EvaluateSocketCall(int aCall) const override {
        switch(aCall) {
        case SYS_RECVFROM:
        case SYS_SENDTO:
            return Some(Allow());

        case SYS_SOCKETPAIR: {
            // See bug 1066750.
            if (!kSocketCallHasArgs) {
                // We can't filter the args if the platform passes them by pointer.
                return Some(Allow());
            }
            Arg<int> domain(0), type(1);
            return Some(If(domain == AF_UNIX &&
                           (type == SOCK_STREAM || type == SOCK_SEQPACKET), Allow())
                        .Else(InvalidSyscall()));
        }

#ifdef ANDROID
        case SYS_SOCKET:
            return Some(Error(EACCES));
#else // #ifdef DESKTOP
        case SYS_RECV:
        case SYS_SEND:
        case SYS_SOCKET: // DANGEROUS
        case SYS_CONNECT: // DANGEROUS
        case SYS_SETSOCKOPT:
        case SYS_GETSOCKNAME:
        case SYS_GETPEERNAME:
        case SYS_SHUTDOWN:
            return Some(Allow());
#endif
        default:
            return SandboxPolicyCommon::EvaluateSocketCall(aCall);
        }
    }
Exemplo n.º 5
0
    virtual ResultExpr EvaluateSyscall(int sysno) const override {
        switch (sysno) {
        // Timekeeping
        case __NR_clock_gettime: {
            Arg<clockid_t> clk_id(0);
            return If(clk_id == CLOCK_MONOTONIC, Allow())
                   .ElseIf(clk_id == CLOCK_REALTIME, Allow())
                   .Else(InvalidSyscall());
        }
        case __NR_gettimeofday:
#ifdef __NR_time
        case __NR_time:
#endif
        case __NR_nanosleep:
            return Allow();

        // Thread synchronization
        case __NR_futex:
            // FIXME: This could be more restrictive....
            return Allow();

        // Asynchronous I/O
        case __NR_epoll_wait:
        case __NR_epoll_pwait:
        case __NR_epoll_ctl:
        case __NR_ppoll:
        case __NR_poll:
            return Allow();

        // Used when requesting a crash dump.
        case __NR_pipe:
            return Allow();

            // Metadata of opened files
CASES_FOR_fstat:
            return Allow();

        // Simple I/O
        case __NR_write:
        case __NR_read:
        case __NR_writev: // see SandboxLogging.cpp
            return Allow();

            // Memory mapping
CASES_FOR_mmap:
        case __NR_munmap:
            return Allow();

            // Signal handling
#if defined(ANDROID) || defined(MOZ_ASAN)
        case __NR_sigaltstack:
#endif
CASES_FOR_sigreturn:
CASES_FOR_sigprocmask:
CASES_FOR_sigaction:
            return Allow();

        // Send signals within the process (raise(), profiling, etc.)
        case __NR_tgkill: {
            Arg<pid_t> tgid(0);
            return If(tgid == getpid(), Allow())
                   .Else(InvalidSyscall());
        }

#if defined(ANDROID) && ANDROID_VERSION < 16
        // Polyfill with tgkill; see above.
        case __NR_tkill:
            return Trap(TKillCompatTrap, nullptr);
#endif

        // Yield
        case __NR_sched_yield:
            return Allow();

        // Thread creation.
        case __NR_clone:
            return ClonePolicy();

            // More thread creation.
#ifdef __NR_set_robust_list
        case __NR_set_robust_list:
            return Allow();
#endif
#ifdef ANDROID
        case __NR_set_tid_address:
            return Allow();
#endif

        // prctl
        case __NR_prctl:
            return PrctlPolicy();

        // NSPR can call this when creating a thread, but it will accept a
        // polite "no".
        case __NR_getpriority:
        // But if thread creation races with sandbox startup, that call
        // could succeed, and then we get one of these:
        case __NR_setpriority:
            return Error(EACCES);

        // Stack bounds are obtained via pthread_getattr_np, which calls
        // this but doesn't actually need it:
        case __NR_sched_getaffinity:
            return Error(ENOSYS);

        // Read own pid/tid.
        case __NR_getpid:
        case __NR_gettid:
            return Allow();

        // Discard capabilities
        case __NR_close:
            return Allow();

            // Machine-dependent stuff
#ifdef __arm__
        case __ARM_NR_breakpoint:
        case __ARM_NR_cacheflush:
        case __ARM_NR_usr26: // FIXME: do we actually need this?
        case __ARM_NR_usr32:
        case __ARM_NR_set_tls:
            return Allow();
#endif

        // Needed when being debugged:
        case __NR_restart_syscall:
            return Allow();

        // Terminate threads or the process
        case __NR_exit:
        case __NR_exit_group:
            return Allow();

#ifdef MOZ_ASAN
        // ASAN's error reporter wants to know if stderr is a tty.
        case __NR_ioctl: {
            Arg<int> fd(0);
            return If(fd == STDERR_FILENO, Allow())
                   .Else(InvalidSyscall());
        }

        // ...and before compiler-rt r209773, it will call readlink on
        // /proc/self/exe and use the cached value only if that fails:
        case __NR_readlink:
        case __NR_readlinkat:
            return Error(ENOENT);

            // ...and if it found an external symbolizer, it will try to run it:
            // (See also bug 1081242 comment #7.)
CASES_FOR_stat:
            return Error(ENOENT);
#endif

        default:
            return SandboxPolicyBase::EvaluateSyscall(sysno);
        }
    }
Exemplo n.º 6
0
sandbox::bpf_dsl::ResultExpr
SandboxPolicyBase::EvaluateSyscall(int aSysno) const {
  switch (aSysno) {
#ifdef __NR_socketcall
    case __NR_socketcall: {
      Arg<int> call(0);
      UniquePtr<Caser<int>> acc(new Caser<int>(Switch(call)));
      for (int i = SYS_SOCKET; i <= SYS_SENDMMSG; ++i) {
        auto thisCase = EvaluateSocketCall(i);
        // Optimize out cases that are equal to the default.
        if (thisCase) {
          acc.reset(new Caser<int>(acc->Case(i, *thisCase)));
        }
      }
      return acc->Default(InvalidSyscall());
    }
#ifndef ANDROID
    case __NR_ipc: {
      Arg<int> callAndVersion(0);
      auto call = callAndVersion & 0xFFFF;
      UniquePtr<Caser<int>> acc(new Caser<int>(Switch(call)));
      for (int i = SEMOP; i <= DIPC; ++i) {
        auto thisCase = EvaluateIpcCall(i);
        // Optimize out cases that are equal to the default.
        if (thisCase) {
          acc.reset(new Caser<int>(acc->Case(i, *thisCase)));
        }
      }
      return acc->Default(InvalidSyscall());
    }
#endif // ANDROID
#else // __NR_socketcall
#define DISPATCH_SOCKETCALL(sysnum, socketnum)         \
    case sysnum:                                       \
      return EvaluateSocketCall(socketnum).valueOr(InvalidSyscall())
      DISPATCH_SOCKETCALL(__NR_socket,      SYS_SOCKET);
      DISPATCH_SOCKETCALL(__NR_bind,        SYS_BIND);
      DISPATCH_SOCKETCALL(__NR_connect,     SYS_CONNECT);
      DISPATCH_SOCKETCALL(__NR_listen,      SYS_LISTEN);
      DISPATCH_SOCKETCALL(__NR_accept,      SYS_ACCEPT);
      DISPATCH_SOCKETCALL(__NR_getsockname, SYS_GETSOCKNAME);
      DISPATCH_SOCKETCALL(__NR_getpeername, SYS_GETPEERNAME);
      DISPATCH_SOCKETCALL(__NR_socketpair,  SYS_SOCKETPAIR);
#ifdef __NR_send
      DISPATCH_SOCKETCALL(__NR_send,        SYS_SEND);
      DISPATCH_SOCKETCALL(__NR_recv,        SYS_RECV);
#endif // __NR_send
      DISPATCH_SOCKETCALL(__NR_sendto,      SYS_SENDTO);
      DISPATCH_SOCKETCALL(__NR_recvfrom,    SYS_RECVFROM);
      DISPATCH_SOCKETCALL(__NR_shutdown,    SYS_SHUTDOWN);
      DISPATCH_SOCKETCALL(__NR_setsockopt,  SYS_SETSOCKOPT);
      DISPATCH_SOCKETCALL(__NR_getsockopt,  SYS_GETSOCKOPT);
      DISPATCH_SOCKETCALL(__NR_sendmsg,     SYS_SENDMSG);
      DISPATCH_SOCKETCALL(__NR_recvmsg,     SYS_RECVMSG);
      DISPATCH_SOCKETCALL(__NR_accept4,     SYS_ACCEPT4);
      DISPATCH_SOCKETCALL(__NR_recvmmsg,    SYS_RECVMMSG);
      DISPATCH_SOCKETCALL(__NR_sendmmsg,    SYS_SENDMMSG);
#undef DISPATCH_SOCKETCALL
#ifndef ANDROID
#define DISPATCH_SYSVCALL(sysnum, ipcnum)         \
    case sysnum:                                  \
      return EvaluateIpcCall(ipcnum).valueOr(InvalidSyscall())
      DISPATCH_SYSVCALL(__NR_semop,       SEMOP);
      DISPATCH_SYSVCALL(__NR_semget,      SEMGET);
      DISPATCH_SYSVCALL(__NR_semctl,      SEMCTL);
      DISPATCH_SYSVCALL(__NR_semtimedop,  SEMTIMEDOP);
      DISPATCH_SYSVCALL(__NR_msgsnd,      MSGSND);
      DISPATCH_SYSVCALL(__NR_msgrcv,      MSGRCV);
      DISPATCH_SYSVCALL(__NR_msgget,      MSGGET);
      DISPATCH_SYSVCALL(__NR_msgctl,      MSGCTL);
      DISPATCH_SYSVCALL(__NR_shmat,       SHMAT);
      DISPATCH_SYSVCALL(__NR_shmdt,       SHMDT);
      DISPATCH_SYSVCALL(__NR_shmget,      SHMGET);
      DISPATCH_SYSVCALL(__NR_shmctl,      SHMCTL);
#undef DISPATCH_SYSVCALL
#endif // ANDROID
#endif // __NR_socketcall
  default:
    return InvalidSyscall();
  }
}