tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

42_linux_32bit_arg_fixup.patch (4027B)


      1 commit e0a00891b67ec162a17aa241a83b171b313de9fe
      2 Author: Jed Davis <jld@mozilla.com>
      3 Date:   Mon Apr 18 18:00:10 2022 -0600
      4 
      5    Make the sandbox fix up non-extended 32-bit types.
      6 
      7 diff --git a/sandbox/linux/bpf_dsl/policy_compiler.cc b/sandbox/linux/bpf_dsl/policy_compiler.cc
      8 index 347304889eae4..b909fc37f6174 100644
      9 --- a/sandbox/linux/bpf_dsl/policy_compiler.cc
     10 +++ b/sandbox/linux/bpf_dsl/policy_compiler.cc
     11 @@ -19,6 +19,7 @@
     12 #include "sandbox/linux/bpf_dsl/policy.h"
     13 #include "sandbox/linux/bpf_dsl/seccomp_macros.h"
     14 #include "sandbox/linux/bpf_dsl/syscall_set.h"
     15 +#include "sandbox/linux/seccomp-bpf/syscall.h"
     16 #include "sandbox/linux/system_headers/linux_filter.h"
     17 #include "sandbox/linux/system_headers/linux_seccomp.h"
     18 #include "sandbox/linux/system_headers/linux_syscalls.h"
     19 @@ -318,8 +319,7 @@ CodeGen::Node PolicyCompiler::MaskedEqualHalf(int argno,
     20     // Special logic for sanity checking the upper 32-bits of 32-bit system
     21     // call arguments.
     22 
     23 -    // TODO(mdempsky): Compile Unexpected64bitArgument() just per program.
     24 -    CodeGen::Node invalid_64bit = Unexpected64bitArgument();
     25 +    CodeGen::Node invalid_64bit = Unexpected64bitArgument(argno);
     26 
     27     const uint32_t upper = SECCOMP_ARG_MSB_IDX(argno);
     28     const uint32_t lower = SECCOMP_ARG_LSB_IDX(argno);
     29 @@ -335,8 +335,13 @@ CodeGen::Node PolicyCompiler::MaskedEqualHalf(int argno,
     30               BPF_JMP + BPF_JEQ + BPF_K, 0, passed, invalid_64bit));
     31     }
     32 
     33 -    // On 64-bit platforms, the upper 32-bits may be 0 or ~0; but we only allow
     34 -    // ~0 if the sign bit of the lower 32-bits is set too:
     35 +    // On 64-bit platforms, the ABI (at least on x86_64) allows any value
     36 +    // for the upper half, but to avoid potential vulnerabilties if an
     37 +    // argument is incorrectly tested as a 32-bit type, we require it to be
     38 +    // either zero-extended or sign-extended.  That is, the upper 32-bits
     39 +    // may be 0 or ~0; but we only allow ~0 if the sign bit of the lower
     40 +    // 32-bits is set too:
     41 +    //
     42     //   LDW  [upper]
     43     //   JEQ  0, passed, (next)
     44     //   JEQ  ~0, (next), invalid
     45 @@ -424,8 +429,18 @@ CodeGen::Node PolicyCompiler::MaskedEqualHalf(int argno,
     46               BPF_JMP + BPF_JEQ + BPF_K, value, passed, failed)));
     47 }
     48 
     49 -CodeGen::Node PolicyCompiler::Unexpected64bitArgument() {
     50 -  return CompileResult(panic_func_("Unexpected 64bit argument detected"));
     51 +CodeGen::Node PolicyCompiler::Unexpected64bitArgument(int argno) {
     52 +  // This situation is unlikely, but possible.  Return to userspace,
     53 +  // zero-extend the problematic argument, and re-issue the syscall.
     54 +  return CompileResult(bpf_dsl::Trap(
     55 +      [](const arch_seccomp_data& args_ref, void* aux) -> intptr_t {
     56 +        arch_seccomp_data args = args_ref;
     57 +        int argno = (int)(intptr_t)aux;
     58 +        args.args[argno] &= 0xFFFFFFFF;
     59 +        return Syscall::Call(args.nr, args.args[0], args.args[1], args.args[2],
     60 +                             args.args[3], args.args[4], args.args[5]);
     61 +      },
     62 +      (void*)(intptr_t)argno));
     63 }
     64 
     65 CodeGen::Node PolicyCompiler::Return(uint32_t ret) {
     66 diff --git a/sandbox/linux/bpf_dsl/policy_compiler.h b/sandbox/linux/bpf_dsl/policy_compiler.h
     67 index 48b1d780d956f..2acf878474a7d 100644
     68 --- a/sandbox/linux/bpf_dsl/policy_compiler.h
     69 +++ b/sandbox/linux/bpf_dsl/policy_compiler.h
     70 @@ -132,9 +132,11 @@ class SANDBOX_EXPORT PolicyCompiler {
     71                                 CodeGen::Node passed,
     72                                 CodeGen::Node failed);
     73 
     74 -  // Returns the fatal CodeGen::Node that is used to indicate that somebody
     75 -  // attempted to pass a 64bit value in a 32bit system call argument.
     76 -  CodeGen::Node Unexpected64bitArgument();
     77 +  // Returns the CodeGen::Node that is used to handle the case where a
     78 +  // system call argument was expected to be a 32-bit type, but the
     79 +  // value in the 64-bit register doesn't correspond to a
     80 +  // zero-extended or sign-extended 32-bit value.
     81 +  CodeGen::Node Unexpected64bitArgument(int argno);
     82 
     83   const Policy* policy_;
     84   TrapRegistry* registry_;