gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/pkg/sentry/platform/ptrace/stub_amd64.s (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 #include "funcdata.h" 16 #include "textflag.h" 17 18 #define SYS_GETPID 39 19 #define SYS_EXIT 60 20 #define SYS_KILL 62 21 #define SYS_GETPPID 110 22 #define SYS_PRCTL 157 23 24 #define SIGKILL 9 25 #define SIGSTOP 19 26 27 #define PR_SET_PDEATHSIG 1 28 29 // stub bootstraps the child and sends itself SIGSTOP to wait for attach. 30 // 31 // R15 contains the expected PPID. R15 is used instead of a more typical DI 32 // since syscalls will clobber DI and createStub wants to pass a new PPID to 33 // grandchildren. 34 // 35 // This should not be used outside the context of a new ptrace child (as the 36 // function is otherwise a bunch of nonsense). 37 TEXT ·stub(SB),NOSPLIT|NOFRAME,$0 38 begin: 39 // N.B. This loop only executes in the context of a single-threaded 40 // fork child. 41 42 MOVQ $SYS_PRCTL, AX 43 MOVQ $PR_SET_PDEATHSIG, DI 44 MOVQ $SIGKILL, SI 45 SYSCALL 46 47 CMPQ AX, $0 48 JNE error 49 50 // If the parent already died before we called PR_SET_DEATHSIG then 51 // we'll have an unexpected PPID. 52 MOVQ $SYS_GETPPID, AX 53 SYSCALL 54 55 CMPQ AX, $0 56 JL error 57 58 CMPQ AX, R15 59 JNE parent_dead 60 61 MOVQ $SYS_GETPID, AX 62 SYSCALL 63 64 CMPQ AX, $0 65 JL error 66 67 MOVQ $0, BX 68 69 // SIGSTOP to wait for attach. 70 // 71 // The SYSCALL instruction will be used for future syscall injection by 72 // thread.syscall. 73 MOVQ AX, DI 74 MOVQ $SYS_KILL, AX 75 MOVQ $SIGSTOP, SI 76 SYSCALL 77 78 // The sentry sets BX to 1 when creating stub process. 79 CMPQ BX, $1 80 JE clone 81 82 // Notify the Sentry that syscall exited. 83 done: 84 INT $3 85 // Be paranoid. 86 JMP done 87 clone: 88 // subprocess.createStub clones a new stub process that is untraced, 89 // thus executing this code. We setup the PDEATHSIG before SIGSTOPing 90 // ourselves for attach by the tracer. 91 // 92 // R15 has been updated with the expected PPID. 93 CMPQ AX, $0 94 JE begin 95 96 // The clone syscall returns a non-zero value. 97 JMP done 98 error: 99 // Exit with -errno. 100 MOVQ AX, DI 101 NEGQ DI 102 MOVQ $SYS_EXIT, AX 103 SYSCALL 104 HLT 105 106 parent_dead: 107 MOVQ $SYS_EXIT, AX 108 MOVQ $1, DI 109 SYSCALL 110 HLT 111 112 // func addrOfStub() uintptr 113 TEXT ·addrOfStub(SB), $0-8 114 MOVQ $·stub(SB), AX 115 MOVQ AX, ret+0(FP) 116 RET 117 118 // stubCall calls the stub function at the given address with the given PPID. 119 // 120 // This is a distinct function because stub, above, may be mapped at any 121 // arbitrary location, and stub has a specific binary API (see above). 122 TEXT ·stubCall(SB),NOSPLIT|NOFRAME,$0-16 123 MOVQ addr+0(FP), AX 124 MOVQ pid+8(FP), R15 125 JMP AX