source/prog/lang-fasm/capwrap.fasm

91 lines
1.6 KiB
Plaintext

format ELF64 executable
include "arch/x86_64-linux.fasm"
PR_CAP_AMBIENT = 47
PR_CAP_AMBIENT_RAISE = 2
upstream:
db '/home/kaction/.nix-profile/bin/ls', 0
hdrp:
.version:
dd 0x20080522
.pid:
dd 0x0
datap:
.effective0:
rd 1
.permitted0:
rd 1
.inheritable0:
rd 1
.effective1:
rd 1
.permitted1:
rd 1
.inheritable1:
rd 1
do_prctl:
.repeat:
bsf edx, ebx ;; edx <- index of first set bit in ebx
jz .done ;; break if ebx is 0
btr ebx, edx ;; clear that bit in ebx
add rdx, r12
;; prctl(PR_CAP_AMBIENT, PR_CAP_AMBIENT_RAISE, edx)
;; %edx is third argument to syscall and it already
;; has value needed.
mov rax, SYS_prctl
mov rdi, PR_CAP_AMBIENT
mov rsi, PR_CAP_AMBIENT_RAISE
syscall
jmp .repeat
.done:
ret
entry $
mov rdi, hdrp
mov rsi, datap
mov rax, SYS_capget
syscall
mov eax, [datap.permitted0]
mov [datap.inheritable0], eax
mov [datap.effective0], eax
mov eax, [datap.permitted1]
mov [datap.inheritable1], eax
mov [datap.effective1], eax
mov rdi, hdrp
mov rsi, datap
mov rax, SYS_capset
syscall
xor r12, r12
mov ebx, [datap.inheritable0]
call do_prctl
mov r12, 32
mov ebx, [datap.inheritable1]
call do_prctl
mov r10, [rsp] ;; r10 := argc
mov qword rdi, upstream ;; rdi := upstream
lea rsi, [rsp + 8] ;; rsi := argv
mov qword [rsi], upstream ;; argv[0] := upstream. Makes busybox happy
lea rdx, [16 + 8 * r10 + rsp] ;; rdx := envp
mov rax, SYS_execve
syscall
;; This should not happen, but segfaulting if execve(2) failed is not
;; nice.
neg rax
mov rdi, rax
mov rax, SYS_exit
syscall