1*ec63e07aSXin Li // Copyright 2019 Google LLC 2*ec63e07aSXin Li // 3*ec63e07aSXin Li // Licensed under the Apache License, Version 2.0 (the "License"); 4*ec63e07aSXin Li // you may not use this file except in compliance with the License. 5*ec63e07aSXin Li // You may obtain a copy of the License at 6*ec63e07aSXin Li // 7*ec63e07aSXin Li // https://www.apache.org/licenses/LICENSE-2.0 8*ec63e07aSXin Li // 9*ec63e07aSXin Li // Unless required by applicable law or agreed to in writing, software 10*ec63e07aSXin Li // distributed under the License is distributed on an "AS IS" BASIS, 11*ec63e07aSXin Li // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*ec63e07aSXin Li // See the License for the specific language governing permissions and 13*ec63e07aSXin Li // limitations under the License. 14*ec63e07aSXin Li 15*ec63e07aSXin Li // This file defines the sandbox2::Regs class stores context of a process 16*ec63e07aSXin Li // during ptrace stop events 17*ec63e07aSXin Li 18*ec63e07aSXin Li #ifndef SANDBOXED_API_SANDBOX2_REGS_H_ 19*ec63e07aSXin Li #define SANDBOXED_API_SANDBOX2_REGS_H_ 20*ec63e07aSXin Li 21*ec63e07aSXin Li #include <sys/types.h> 22*ec63e07aSXin Li 23*ec63e07aSXin Li #include <cstdint> 24*ec63e07aSXin Li 25*ec63e07aSXin Li #include "absl/status/status.h" 26*ec63e07aSXin Li #include "sandboxed_api/config.h" 27*ec63e07aSXin Li #include "sandboxed_api/sandbox2/syscall.h" 28*ec63e07aSXin Li #include "sandboxed_api/sandbox2/violation.pb.h" 29*ec63e07aSXin Li 30*ec63e07aSXin Li namespace sandbox2 { 31*ec63e07aSXin Li 32*ec63e07aSXin Li // Helper class to get and modify running processes registers. Uses ptrace and 33*ec63e07aSXin Li // assumes the process is already attached. 34*ec63e07aSXin Li class Regs { 35*ec63e07aSXin Li public: Regs(pid_t pid)36*ec63e07aSXin Li explicit Regs(pid_t pid) : pid_(pid) {} 37*ec63e07aSXin Li 38*ec63e07aSXin Li // Copies register values from the process 39*ec63e07aSXin Li absl::Status Fetch(); 40*ec63e07aSXin Li 41*ec63e07aSXin Li // Copies register values to the process 42*ec63e07aSXin Li absl::Status Store(); 43*ec63e07aSXin Li 44*ec63e07aSXin Li // Causes the process to skip current syscall and return given value instead 45*ec63e07aSXin Li absl::Status SkipSyscallReturnValue(uintptr_t value); 46*ec63e07aSXin Li 47*ec63e07aSXin Li // Converts raw register values obtained on syscall entry to syscall info 48*ec63e07aSXin Li Syscall ToSyscall(sapi::cpu::Architecture syscall_arch) const; 49*ec63e07aSXin Li 50*ec63e07aSXin Li // Returns the content of the register that holds a syscall's return value 51*ec63e07aSXin Li int64_t GetReturnValue(sapi::cpu::Architecture syscall_arch) const; 52*ec63e07aSXin Li pid()53*ec63e07aSXin Li pid_t pid() const { return pid_; } 54*ec63e07aSXin Li 55*ec63e07aSXin Li // Stores register values in a protobuf structure. 56*ec63e07aSXin Li void StoreRegisterValuesInProtobuf(RegisterValues* values) const; 57*ec63e07aSXin Li 58*ec63e07aSXin Li private: 59*ec63e07aSXin Li friend class StackTracePeer; 60*ec63e07aSXin Li 61*ec63e07aSXin Li struct PtraceRegisters { 62*ec63e07aSXin Li #if defined(SAPI_X86_64) 63*ec63e07aSXin Li uint64_t r15; 64*ec63e07aSXin Li uint64_t r14; 65*ec63e07aSXin Li uint64_t r13; 66*ec63e07aSXin Li uint64_t r12; 67*ec63e07aSXin Li uint64_t rbp; 68*ec63e07aSXin Li uint64_t rbx; 69*ec63e07aSXin Li uint64_t r11; 70*ec63e07aSXin Li uint64_t r10; 71*ec63e07aSXin Li uint64_t r9; 72*ec63e07aSXin Li uint64_t r8; 73*ec63e07aSXin Li uint64_t rax; 74*ec63e07aSXin Li uint64_t rcx; 75*ec63e07aSXin Li uint64_t rdx; 76*ec63e07aSXin Li uint64_t rsi; 77*ec63e07aSXin Li uint64_t rdi; 78*ec63e07aSXin Li uint64_t orig_rax; 79*ec63e07aSXin Li uint64_t rip; 80*ec63e07aSXin Li uint64_t cs; 81*ec63e07aSXin Li uint64_t eflags; 82*ec63e07aSXin Li uint64_t rsp; 83*ec63e07aSXin Li uint64_t ss; 84*ec63e07aSXin Li uint64_t fs_base; 85*ec63e07aSXin Li uint64_t gs_base; 86*ec63e07aSXin Li uint64_t ds; 87*ec63e07aSXin Li uint64_t es; 88*ec63e07aSXin Li uint64_t fs; 89*ec63e07aSXin Li uint64_t gs; 90*ec63e07aSXin Li #elif defined(SAPI_PPC64_LE) 91*ec63e07aSXin Li uint64_t gpr[32]; 92*ec63e07aSXin Li uint64_t nip; 93*ec63e07aSXin Li uint64_t msr; 94*ec63e07aSXin Li uint64_t orig_gpr3; 95*ec63e07aSXin Li uint64_t ctr; 96*ec63e07aSXin Li uint64_t link; 97*ec63e07aSXin Li uint64_t xer; 98*ec63e07aSXin Li uint64_t ccr; 99*ec63e07aSXin Li uint64_t softe; 100*ec63e07aSXin Li uint64_t trap; 101*ec63e07aSXin Li uint64_t dar; 102*ec63e07aSXin Li uint64_t dsisr; 103*ec63e07aSXin Li uint64_t result; 104*ec63e07aSXin Li // elf.h's ELF_NGREG says it's 48 registers, so kernel fills it in with some 105*ec63e07aSXin Li // zeroes. 106*ec63e07aSXin Li uint64_t zero0; 107*ec63e07aSXin Li uint64_t zero1; 108*ec63e07aSXin Li uint64_t zero2; 109*ec63e07aSXin Li uint64_t zero3; 110*ec63e07aSXin Li #elif defined(SAPI_ARM64) 111*ec63e07aSXin Li uint64_t regs[31]; 112*ec63e07aSXin Li uint64_t sp; 113*ec63e07aSXin Li uint64_t pc; 114*ec63e07aSXin Li uint64_t pstate; 115*ec63e07aSXin Li #elif defined(SAPI_ARM) 116*ec63e07aSXin Li uint32_t regs[15]; 117*ec63e07aSXin Li uint32_t pc; 118*ec63e07aSXin Li uint32_t cpsr; 119*ec63e07aSXin Li uint32_t orig_x0; 120*ec63e07aSXin Li #else 121*ec63e07aSXin Li static_assert(false, "Host CPU architecture not supported, see config.h"); 122*ec63e07aSXin Li #endif 123*ec63e07aSXin Li }; 124*ec63e07aSXin Li 125*ec63e07aSXin Li // PID for which registers are fetched/stored 126*ec63e07aSXin Li pid_t pid_ = 0; 127*ec63e07aSXin Li 128*ec63e07aSXin Li // Registers fetched with ptrace(PR_GETREGS/GETREGSET, pid). 129*ec63e07aSXin Li PtraceRegisters user_regs_ = {}; 130*ec63e07aSXin Li 131*ec63e07aSXin Li // On AArch64, obtaining the syscall number needs a specific call to ptrace() 132*ec63e07aSXin Li int syscall_number_ = 0; 133*ec63e07aSXin Li }; 134*ec63e07aSXin Li 135*ec63e07aSXin Li } // namespace sandbox2 136*ec63e07aSXin Li 137*ec63e07aSXin Li #endif // SANDBOXED_API_SANDBOX2_REGS_H_ 138