amd64-linux.elf shlib now fully-SELinux compliant

modified:   stub/src/amd64-linux.elf-so_entry.S
	modified:   stub/src/amd64-linux.elf-so_fold.S
This commit is contained in:
John Reiser 2023-04-26 13:06:48 -07:00
parent be6e77379a
commit 0901ce1b68
2 changed files with 65 additions and 42 deletions

View File

@ -31,6 +31,7 @@
#include "arch/amd64/macros.S"
#include "arch/amd64/regs.h"
NBPW= 8
sz_Ehdr= 64
sz_Phdr= 56
@ -56,8 +57,10 @@ MAP_ANONYMOUS= 0x20
__NR_mmap= 9 // 64-bit mode only! /usr/include/asm/unistd_64.h
__NR_mprotect= 10
__NR_munmap= 11
__NR_memfd_create= 0x13f // 319
__NR_write= 1
__NR_close= 3
__NR_exit= 60
PAGE_SHIFT= 12
@ -85,8 +88,9 @@ _start:
push %arg3 // MATCH_07 envp (glibc)
push %arg2 // MATCH_01 argv
push %arg1 // MATCH_00 argc
push %rbp // MATCH_02 saved register
push %rbx // MATCH_03 saved register
push %rbp // MATCH_02 saved register
mov %rsp,%rbp
call L70 // MATCH_08 push $&getbit
/* Working registers */
#define off %eax /* XXX: 2GB */
@ -111,24 +115,16 @@ refill:
adcl bits,bits // LSB= 1 (CarryIn); CarryOut= next bit
ret // infrequent (1/32)
L20:
L20: // %rdx == &getbit
pop %rbx // MATCH_09 &fold_info
lea _start - 4*4 - getbit(%rdx),%rax // &so_info
push %rax // MATCH_14 &so_info
// cmpw $M_NRV2B_LE32|(0<<8),b_method(%rbx); je 0f; hlt; 0: // check method and filter bytes
// Get pages for unfolded code
sub %arg6,%arg6 // 0
pop %rdx // MATCH_08 &getbit
sub %arg5,%arg5 // 0
movl /*sz_unc*/(%rbx),%arg2l // dstlen
push $MAP_PRIVATE|MAP_ANONYMOUS; pop %sys4
push %arg2 // MATCH_10 len for escape hatch
push %rdx // MATCH_15 save &getbit over syscall
push $PROT_READ|PROT_WRITE; pop %arg3
subl %edi,%edi // (%arg1)dst = 0; // kernel chooses
push $__NR_mmap; pop %rax; syscall; cmp $-4096,%rax; jb 0f; int3; 0:
pop %rdx // MATCH_15 &getbit
push %rax // MATCH_04 ptr unfolded_code
// De-compress folded code onto the stack
movl /*sz_unc*/(%rbx),%eax; push %rax // MATCH_40 len unfolded code
sub %rax,%rsp; and $-2*NBPW,%rsp
// This is nrv2b_d32, inlined and optimized for small space (about 160 bytes).
// The task is to de-compress the folded pieces for shared library init:
@ -140,7 +136,8 @@ L20:
// and compressability of C-coded de-compressors for Lzma and Zstd
// in contrast to the simple and small assembly-coded NRV.
push %rax; pop dst // &unfolded_code
push %rsp; pop dst // &unfolded_code
push %rbp // MATCH_45
movl sz_cpr(%rbx),len // lsrc
lea sz_b_info(%rbx),src
decompress: // inlined: (uchar const *src, uint len, uchar *dst /*, u32 &ldst, uint method */)
@ -150,8 +147,9 @@ decompress: // inlined: (uchar const *src, uint len, uchar *dst /*, u32 &ldst,
// MATCH_05 &input_eof
// MATCH_04 ptr unfolded_code
// MATCH_10 len unfolded_code
// MATCH_03 saved %rbx
//%rbp:
// MATCH_02 saved %rbp
// MATCH_03 saved %rbx
// MATCH_00 argc
// MATCH_01 argv
// MATCH_07 envp
@ -201,33 +199,57 @@ gotlen_n2b:
eof_n2b:
pop %rcx // MATCH_05 &input_eof
cmp %rcx,%rsi; je 0f; hlt; 0: // test for ending in correct place
lea _start - 4*4 - getbit(%rdx),%rdx // &so_info
pop %arg1 // MATCH_11 ptr unfolded code
pop %arg2 // MATCH_10 len unfolded code
push %rdx // MATCH_14 &so_info
push %arg2 // MATCH_12 len unfolded code
push %arg1 // MATCH_13 ptr unfolded code
push $PROT_EXEC|PROT_READ; pop %arg3
push $__NR_mprotect; pop %rax; syscall; cmp $-4096,%rax; jb 0f; int3; 0:
pop %rbp // MATCH_45
push $0; pop %arg2
call 0f; .asciz "upx"; 0: pop %arg1
mov $__NR_memfd_create,%rax; call do_sys
push %rax; pop %arg1 // mfd
push %rsp; pop %arg2 // buffer
push %rax // MATCH_47 save mfd
mov -2*NBPW(%rbp),%arg3 // length
push $__NR_write; pop %rax; call do_sys // scribbles %rcx !!
// Map unfolded code the SELinux way
pop %arg5 // MATCH_47 mfd
lea -2*NBPW(%rbp),%rsp
pop %arg2; push %arg2 // MATCH_40 len unfolded code
sub %arg6l,%arg6l // 0
push $MAP_PRIVATE; pop %sys4
push $PROT_READ|PROT_EXEC; pop %arg3
subl %edi,%edi // (%arg1)dst = 0; // kernel chooses addr
push $__NR_mmap; pop %rax; call do_sys
push %rax // MATCH_11 ptr unfolded code
push %arg5; pop %arg1 // mfd
push $__NR_close; pop %rax; call do_sys
// %rsp:
// MATCH_13 ptr unfolded_code; for escape hatch
// MATCH_12 len unfolded code; for escape hatch
// MATCH_11 ptr unfolded_code; for escape hatch
// MATCH_10 len unfolded code; for escape hatch
// MATCH_14 &so_info
// MATCH_03 saved %rbx
// %rbp:
// MATCH_02 saved %rbp
// MATCH_03 saved %rbx
// MATCH_00 argc
// MATCH_01 argv
// MATCH_07 envp
pop %rax; push %rax // MATCH_13 ptr unfolded code
pop %rax; push %rax // MATCH_11 ptr unfolded code
jmp *%rax // enter C code
do_sys:
syscall
cmp $-4096,%rax; jb 0f; int3; 0:
ret
// IDENTSTR goes here
section ELFMAINZ
L70:
pop %rdx // MATCH_08 &getbit
call L20 // MATCH_09 push $&fold_info
fold_info:
// b_info (sz_unc, sz_cpr, method) of folded code (C-language, etc.)

View File

@ -8,33 +8,34 @@ NBPW= 8
#endif //}
// %rsp:
// MATCH_13 ptr unfolded_code; for escape hatch
// MATCH_12 len unfolded code; for escape hatch
// MATCH_11 ptr unfolded_code; for escape hatch
// MATCH_10 len unfolded code; for escape hatch
// MATCH_14 &so_info:
// .long offset(.) // detect relocation
// .long offset(user DT_INIT)
// .long offset(escape_hatch)
// .long offset({l_info; p_info; b_info; compressed data})
// MATCH_03 saved %rbx
// .word offset(.) // detect relocation
// .word offset(user DT_INIT)
// .word offset(escape_hatch)
// .word offset({l_info; p_info; b_info; compressed data})
// %rbp:
// MATCH_02 saved %rbp
// MATCH_03 saved %rbx
// MATCH_00 argc
// MATCH_01 argv
// MATCH_07 envp
section SO_HEAD
fold:
pop %rbx // MATCH_13 ptr unfolded code
pop %rbp // MATCH_12 len unfolded code
pop %rbx // MATCH_11 ptr unfolded code
pop %rbp // MATCH_10 len unfolded code
pop %arg1 // MATCH_14 &so_info
lea 2*NBPW(%rsp),%arg2 // skip MATCH_03, MATCH_02; MATCH_00 &{argc, argv, envp}
lea 2*NBPW(%rsp),%arg2 // &{argc, argv, envp}
sub $MAX_ELF_HDR_64,%rsp; mov %rsp,%arg3 // space for Elf64_Ehdr and Elf64_Phdrs
call upx_so_main // (&so_info, &{argc, argv, envp}, elf_tmp); returns &escape_hatch
add $MAX_ELF_HDR_64,%rsp
push %rbp; pop %arg2 // len unfolded code
push %rbx; pop %arg1 // ptr unfolded code
pop %rbx // MATCH_03 restore
pop %rbp // MATCH_02 restore
pop %rbx // MATCH_03 restore
push %rax // MATCH_30 &escape_hatch
push $__NR_munmap; pop %rax
ret // MATCH_30 ==>escape_hatch:
@ -73,7 +74,7 @@ eof: // end of a compressed extent
// Subroutines and syscalls needed by upx_so_main
//
my_bkpt: .globl my_bkpt
int3
int3 // my_bkpt
ret
memset: .globl memset // void *memset(void *s, int c, size_t n);