github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/pkg/sentry/arch/arch.go (about) 1 // Copyright 2018 The gVisor Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // Package arch provides abstractions around architecture-dependent details, 16 // such as syscall calling conventions, native types, etc. 17 package arch 18 19 import ( 20 "fmt" 21 "io" 22 23 "github.com/SagerNet/gvisor/pkg/abi/linux" 24 "github.com/SagerNet/gvisor/pkg/cpuid" 25 "github.com/SagerNet/gvisor/pkg/hostarch" 26 "github.com/SagerNet/gvisor/pkg/log" 27 "github.com/SagerNet/gvisor/pkg/marshal" 28 "github.com/SagerNet/gvisor/pkg/sentry/arch/fpu" 29 "github.com/SagerNet/gvisor/pkg/sentry/limits" 30 ) 31 32 // Arch describes an architecture. 33 type Arch int 34 35 const ( 36 // AMD64 is the x86-64 architecture. 37 AMD64 Arch = iota 38 // ARM64 is the aarch64 architecture. 39 ARM64 40 ) 41 42 // String implements fmt.Stringer. 43 func (a Arch) String() string { 44 switch a { 45 case AMD64: 46 return "amd64" 47 case ARM64: 48 return "arm64" 49 default: 50 return fmt.Sprintf("Arch(%d)", a) 51 } 52 } 53 54 // Context provides architecture-dependent information for a specific thread. 55 // 56 // NOTE(b/34169503): Currently we use uintptr here to refer to a generic native 57 // register value. While this will work for the foreseeable future, it isn't 58 // strictly correct. We may want to create some abstraction that makes this 59 // more clear or enables us to store values of arbitrary widths. This is 60 // particularly true for RegisterMap(). 61 type Context interface { 62 // Arch returns the architecture for this Context. 63 Arch() Arch 64 65 // Native converts a generic type to a native value. 66 // 67 // Because the architecture is not specified here, we may be dealing 68 // with return values of varying sizes (for example ARCH_GETFS). This 69 // is a simple utility function to convert to the native size in these 70 // cases, and then we can CopyOut. 71 Native(val uintptr) marshal.Marshallable 72 73 // Value converts a native type back to a generic value. 74 // Once a value has been converted to native via the above call -- it 75 // can be converted back here. 76 Value(val marshal.Marshallable) uintptr 77 78 // Width returns the number of bytes for a native value. 79 Width() uint 80 81 // Fork creates a clone of the context. 82 Fork() Context 83 84 // SyscallNo returns the syscall number. 85 SyscallNo() uintptr 86 87 // SyscallSaveOrig save orignal register value. 88 SyscallSaveOrig() 89 90 // SyscallArgs returns the syscall arguments in an array. 91 SyscallArgs() SyscallArguments 92 93 // Return returns the return value for a system call. 94 Return() uintptr 95 96 // SetReturn sets the return value for a system call. 97 SetReturn(value uintptr) 98 99 // RestartSyscall reverses over the current syscall instruction, such that 100 // when the application resumes execution the syscall will be re-attempted. 101 RestartSyscall() 102 103 // RestartSyscallWithRestartBlock reverses over the current syscall 104 // instraction and overwrites the current syscall number with that of 105 // restart_syscall(2). This causes the application to restart the current 106 // syscall with a custom function when execution resumes. 107 RestartSyscallWithRestartBlock() 108 109 // IP returns the current instruction pointer. 110 IP() uintptr 111 112 // SetIP sets the current instruction pointer. 113 SetIP(value uintptr) 114 115 // Stack returns the current stack pointer. 116 Stack() uintptr 117 118 // SetStack sets the current stack pointer. 119 SetStack(value uintptr) 120 121 // TLS returns the current TLS pointer. 122 TLS() uintptr 123 124 // SetTLS sets the current TLS pointer. Returns false if value is invalid. 125 SetTLS(value uintptr) bool 126 127 // SetOldRSeqInterruptedIP sets the register that contains the old IP 128 // when an "old rseq" restartable sequence is interrupted. 129 SetOldRSeqInterruptedIP(value uintptr) 130 131 // StateData returns a pointer to underlying architecture state. 132 StateData() *State 133 134 // RegisterMap returns a map of all registers. 135 RegisterMap() (map[string]uintptr, error) 136 137 // SignalSetup modifies the context in preparation for handling the 138 // given signal. 139 // 140 // st is the stack where the signal handler frame should be 141 // constructed. 142 // 143 // act is the SigAction that specifies how this signal is being 144 // handled. 145 // 146 // info is the SignalInfo of the signal being delivered. 147 // 148 // alt is the alternate signal stack (even if the alternate signal 149 // stack is not going to be used). 150 // 151 // sigset is the signal mask before entering the signal handler. 152 SignalSetup(st *Stack, act *linux.SigAction, info *linux.SignalInfo, alt *linux.SignalStack, sigset linux.SignalSet) error 153 154 // SignalRestore restores context after returning from a signal 155 // handler. 156 // 157 // st is the current thread stack. 158 // 159 // rt is true if SignalRestore is being entered from rt_sigreturn and 160 // false if SignalRestore is being entered from sigreturn. 161 // SignalRestore returns the thread's new signal mask. 162 SignalRestore(st *Stack, rt bool) (linux.SignalSet, linux.SignalStack, error) 163 164 // CPUIDEmulate emulates a CPUID instruction according to current register state. 165 CPUIDEmulate(l log.Logger) 166 167 // SingleStep returns true if single stepping is enabled. 168 SingleStep() bool 169 170 // SetSingleStep enables single stepping. 171 SetSingleStep() 172 173 // ClearSingleStep disables single stepping. 174 ClearSingleStep() 175 176 // FloatingPointData will be passed to underlying save routines. 177 FloatingPointData() *fpu.State 178 179 // NewMmapLayout returns a layout for a new MM, where MinAddr for the 180 // returned layout must be no lower than min, and MaxAddr for the returned 181 // layout must be no higher than max. Repeated calls to NewMmapLayout may 182 // return different layouts. 183 NewMmapLayout(min, max hostarch.Addr, limits *limits.LimitSet) (MmapLayout, error) 184 185 // PIELoadAddress returns a preferred load address for a 186 // position-independent executable within l. 187 PIELoadAddress(l MmapLayout) hostarch.Addr 188 189 // FeatureSet returns the FeatureSet in use in this context. 190 FeatureSet() *cpuid.FeatureSet 191 192 // Hack around our package dependences being too broken to support the 193 // equivalent of arch_ptrace(): 194 195 // PtracePeekUser implements ptrace(PTRACE_PEEKUSR). 196 PtracePeekUser(addr uintptr) (marshal.Marshallable, error) 197 198 // PtracePokeUser implements ptrace(PTRACE_POKEUSR). 199 PtracePokeUser(addr, data uintptr) error 200 201 // PtraceGetRegs implements ptrace(PTRACE_GETREGS) by writing the 202 // general-purpose registers represented by this Context to dst and 203 // returning the number of bytes written. 204 PtraceGetRegs(dst io.Writer) (int, error) 205 206 // PtraceSetRegs implements ptrace(PTRACE_SETREGS) by reading 207 // general-purpose registers from src into this Context and returning the 208 // number of bytes read. 209 PtraceSetRegs(src io.Reader) (int, error) 210 211 // PtraceGetRegSet implements ptrace(PTRACE_GETREGSET) by writing the 212 // register set given by architecture-defined value regset from this 213 // Context to dst and returning the number of bytes written, which must be 214 // less than or equal to maxlen. 215 PtraceGetRegSet(regset uintptr, dst io.Writer, maxlen int) (int, error) 216 217 // PtraceSetRegSet implements ptrace(PTRACE_SETREGSET) by reading the 218 // register set given by architecture-defined value regset from src and 219 // returning the number of bytes read, which must be less than or equal to 220 // maxlen. 221 PtraceSetRegSet(regset uintptr, src io.Reader, maxlen int) (int, error) 222 223 // FullRestore returns 'true' if all CPU registers must be restored 224 // when switching to the untrusted application. Typically a task enters 225 // and leaves the kernel via a system call. Platform.Switch() may 226 // optimize for this by not saving/restoring all registers if allowed 227 // by the ABI. For e.g. the amd64 ABI specifies that syscall clobbers 228 // %rcx and %r11. If FullRestore returns true then these optimizations 229 // must be disabled and all registers restored. 230 FullRestore() bool 231 } 232 233 // MmapDirection is a search direction for mmaps. 234 type MmapDirection int 235 236 const ( 237 // MmapBottomUp instructs mmap to prefer lower addresses. 238 MmapBottomUp MmapDirection = iota 239 240 // MmapTopDown instructs mmap to prefer higher addresses. 241 MmapTopDown 242 ) 243 244 // MmapLayout defines the layout of the user address space for a particular 245 // MemoryManager. 246 // 247 // Note that "highest address" below is always exclusive. 248 // 249 // +stateify savable 250 type MmapLayout struct { 251 // MinAddr is the lowest mappable address. 252 MinAddr hostarch.Addr 253 254 // MaxAddr is the highest mappable address. 255 MaxAddr hostarch.Addr 256 257 // BottomUpBase is the lowest address that may be returned for a 258 // MmapBottomUp mmap. 259 BottomUpBase hostarch.Addr 260 261 // TopDownBase is the highest address that may be returned for a 262 // MmapTopDown mmap. 263 TopDownBase hostarch.Addr 264 265 // DefaultDirection is the direction for most non-fixed mmaps in this 266 // layout. 267 DefaultDirection MmapDirection 268 269 // MaxStackRand is the maximum randomization to apply to stack 270 // allocations to maintain a proper gap between the stack and 271 // TopDownBase. 272 MaxStackRand uint64 273 } 274 275 // Valid returns true if this layout is valid. 276 func (m *MmapLayout) Valid() bool { 277 if m.MinAddr > m.MaxAddr { 278 return false 279 } 280 if m.BottomUpBase < m.MinAddr { 281 return false 282 } 283 if m.BottomUpBase > m.MaxAddr { 284 return false 285 } 286 if m.TopDownBase < m.MinAddr { 287 return false 288 } 289 if m.TopDownBase > m.MaxAddr { 290 return false 291 } 292 return true 293 } 294 295 // SyscallArgument is an argument supplied to a syscall implementation. The 296 // methods used to access the arguments are named after the ***C type name*** and 297 // they convert to the closest Go type available. For example, Int() refers to a 298 // 32-bit signed integer argument represented in Go as an int32. 299 // 300 // Using the accessor methods guarantees that the conversion between types is 301 // correct, taking into account size and signedness (i.e., zero-extension vs 302 // signed-extension). 303 type SyscallArgument struct { 304 // Prefer to use accessor methods instead of 'Value' directly. 305 Value uintptr 306 } 307 308 // SyscallArguments represents the set of arguments passed to a syscall. 309 type SyscallArguments [6]SyscallArgument 310 311 // Pointer returns the hostarch.Addr representation of a pointer argument. 312 func (a SyscallArgument) Pointer() hostarch.Addr { 313 return hostarch.Addr(a.Value) 314 } 315 316 // Int returns the int32 representation of a 32-bit signed integer argument. 317 func (a SyscallArgument) Int() int32 { 318 return int32(a.Value) 319 } 320 321 // Uint returns the uint32 representation of a 32-bit unsigned integer argument. 322 func (a SyscallArgument) Uint() uint32 { 323 return uint32(a.Value) 324 } 325 326 // Int64 returns the int64 representation of a 64-bit signed integer argument. 327 func (a SyscallArgument) Int64() int64 { 328 return int64(a.Value) 329 } 330 331 // Uint64 returns the uint64 representation of a 64-bit unsigned integer argument. 332 func (a SyscallArgument) Uint64() uint64 { 333 return uint64(a.Value) 334 } 335 336 // SizeT returns the uint representation of a size_t argument. 337 func (a SyscallArgument) SizeT() uint { 338 return uint(a.Value) 339 } 340 341 // ModeT returns the int representation of a mode_t argument. 342 func (a SyscallArgument) ModeT() uint { 343 return uint(uint16(a.Value)) 344 }