arm32 shlib works with SELinux
modified: stub/src/arch/arm/v4a/macros.S modified: stub/src/arm.v4a-linux.elf-so_entry.S modified: stub/src/arm.v4a-linux.elf-so_fold.S modified: stub/src/arm64-linux.elf-so_entry.S modified: stub/src/i386-linux.elf-so_main.c
This commit is contained in:
parent
937d4462ca
commit
0cffeca102
@ -72,9 +72,11 @@ __NR_SYSCALL_BASE = 0
|
||||
mov r7,r12 // restore r7 from ip
|
||||
.endm
|
||||
.macro do_sys7t2 N // "7t2": two-byte N; clobbers r7 as a temporary
|
||||
mov r12,r7 // save r7 in ip
|
||||
mov r7, #(\N) & 0xff // syscall number
|
||||
orr r7,r7,#(\N) &~0xff // high bits
|
||||
swi 0
|
||||
mov r7,r12 // restore r7 from ip
|
||||
.endm
|
||||
.macro do_sys2 N // two-byte N; clobbers 'ip' (r12), saves r7
|
||||
mov r12,r7 // save r7 in ip
|
||||
|
||||
@ -67,11 +67,13 @@ PAGE_SHIFT= 12
|
||||
PAGE_MASK= (~0<<PAGE_SHIFT)
|
||||
PAGE_SIZE= -PAGE_MASK
|
||||
|
||||
__NR_close= 6 + __NR_SYSCALL_BASE
|
||||
__NR_exit = 1 + __NR_SYSCALL_BASE
|
||||
__NR_write = 4 + __NR_SYSCALL_BASE
|
||||
__NR_memfd_create= 0x181 + __NR_SYSCALL_BASE // 385
|
||||
__NR_mmap64 = 0xc0 + __NR_SYSCALL_BASE
|
||||
__NR_mprotect =125 + __NR_SYSCALL_BASE
|
||||
__NR_munmap = 91 + __NR_SYSCALL_BASE
|
||||
__NR_write = 4 + __NR_SYSCALL_BASE
|
||||
|
||||
__ARM_NR_BASE = 0xf0000 + __NR_SYSCALL_BASE
|
||||
__ARM_NR_cacheflush = 2 + __ARM_NR_BASE
|
||||
@ -142,7 +144,7 @@ _start: .globl _start // in Thumb mode (via PackLinuxElf32::pack3)
|
||||
bkpt // DEBUG
|
||||
#endif //}
|
||||
// argc,argv,envp, r3 convenience, r4-r7 callee-saved, lr ret_addr
|
||||
stmfd sp!,{r0,r1,r2, r3, r4,r5,r6,r7, lr}
|
||||
stmfd sp!,{r0,r1,r2, r3, r4,r5,r6,r7, lr} // MATCH_99
|
||||
|
||||
sub sp,sp,#2*NBPW // space for ADRU, LENU
|
||||
F_ADRU= 0 * NBPW
|
||||
@ -151,34 +153,51 @@ F_ARGC= 2 * NBPW
|
||||
|
||||
call4 L70
|
||||
L70_ret:
|
||||
foldi .req lr // &fold_info
|
||||
mov arg6,#0 // cleanliness
|
||||
mvn arg5,#~-1 // fd= -1
|
||||
mov arg4,#MAP_PRIVATE|MAP_ANONYMOUS // modes
|
||||
mov arg3,#PROT_READ|PROT_WRITE // prot
|
||||
ldr arg2,[foldi, #sz_unc] // dstlen
|
||||
str arg2,[sp, #F_LENU]
|
||||
mov arg1,#0 // addr (kernel chooses)
|
||||
PUSH {foldi} // defend against lr clobbered by syscall
|
||||
do_sys7t __NR_mmap64; cmn r0,#4096; bcc 0f; bkpt; 0:
|
||||
POP {foldi}
|
||||
str r0,[sp, #F_ADRU]
|
||||
foldi .req lr // &fold_info
|
||||
old_sp .req r5 // busy: lr,r5
|
||||
mov old_sp,sp
|
||||
ldr r0,[foldi,#sz_unc]
|
||||
str r0,[old_sp,#F_LENU]
|
||||
sub r0,sp,r0 // alloca
|
||||
and sp,r0,#-2*NBPW // align stack
|
||||
|
||||
add arg4,sp,#F_LENU // &dstlen
|
||||
mov arg3,r0 // dst
|
||||
ldr arg2,[foldi, #sz_cpr] // srclen
|
||||
add arg4,old_sp,#F_LENU // &dstlen
|
||||
mov arg3,sp // dst for decompress
|
||||
ldr arg2,[foldi,#sz_cpr] // srclen
|
||||
add arg1,foldi,#sz_b_info // src
|
||||
call4 f_decompress // includes cache flush
|
||||
.unreq foldi // busy: r5
|
||||
bl f_decompress
|
||||
|
||||
ldr arg1,[sp, #F_ADRU]
|
||||
ldr arg2,[sp, #F_LENU]
|
||||
mov arg3,#PROT_EXEC|PROT_READ
|
||||
do_sys7t __NR_mprotect
|
||||
mov arg2,#0
|
||||
adr arg1,str_upx
|
||||
mfd .req r6 // busy: r6,r5
|
||||
do_sys7t2 __NR_memfd_create; mov mfd,r0
|
||||
|
||||
mov arg2,sp
|
||||
ldr arg3,[old_sp,#F_LENU]
|
||||
do_sys __NR_write
|
||||
mov sp,old_sp // de-alloca
|
||||
.unreq old_sp // busy: r6
|
||||
|
||||
mov arg6,#0 // beginning of file
|
||||
mov arg5,mfd
|
||||
mov arg4,#MAP_PRIVATE // modes
|
||||
mov arg3,#PROT_READ|PROT_EXEC // prot
|
||||
ldr arg2,[sp,#F_LENU]
|
||||
mov arg1,#0 // addr (kernel chooses)
|
||||
do_sys __NR_mmap64; str r0,[sp,#F_ADRU]
|
||||
|
||||
mov arg1,mfd
|
||||
.unreq mfd // busy: empty
|
||||
do_sys __NR_close
|
||||
|
||||
adr r0,_start -4 *NBPW // &SO_INFO
|
||||
add r1,sp,#F_ARGC
|
||||
ldr pc,[sp, #F_ADRU] // invoke folded code
|
||||
|
||||
str_upx:
|
||||
.asciz "upx"
|
||||
|
||||
f_decompress:
|
||||
#define LINUX_ARM_CACHEFLUSH 1
|
||||
#include "arch/arm/v4a/nrv2b_d8.S"
|
||||
|
||||
@ -29,6 +29,7 @@
|
||||
|
||||
#define ARM_OLDABI 1
|
||||
#include "arch/arm/v4a/macros.S"
|
||||
#include "MAX_ELF_HDR.S"
|
||||
#define bkpt .long 0xe7f001f0 /* reserved instr "udf #0x10"; Linux GNU eabi breakpoint */
|
||||
NBPW= 4
|
||||
|
||||
@ -73,15 +74,9 @@ PATH_MAX= 4096
|
||||
mflg_data: .int MAP_PRIVATE|MAP_ANONYMOUS @ overwritten for QNX vs Linux
|
||||
|
||||
// %esp:
|
||||
// &Elf32_Ehdr
|
||||
// &{l_info; p_info; b_info; compressed data}
|
||||
// &escape_hatch
|
||||
// MATCH_13 ptr unfolded_code; for escape hatch
|
||||
// MATCH_12 len unfolded code; for escape hatch
|
||||
// &entry ??
|
||||
// MATCH_00 argc
|
||||
// MATCH_01 argv
|
||||
// MATCH_07 envp
|
||||
// MATCH_99 9 saved registers {r0= argc, r1= argv, r2= envp, r3-r7, lr)
|
||||
|
||||
F_ADRU= 0 * NBPW
|
||||
F_LENU= 2 * NBPW
|
||||
@ -90,7 +85,9 @@ F_LENU= 2 * NBPW
|
||||
|
||||
section SO_HEAD
|
||||
fold: .globl fold
|
||||
sub sp,sp,#MAX_ELF_HDR_32; mov r2,sp // &elf_tmp
|
||||
call upx_so_main // (&so_info, &argc); returns &escape_hatch
|
||||
add sp,sp,#MAX_ELF_HDR_32
|
||||
mov lr,r0 // save &escape_hatch
|
||||
ldmia sp!,{r0,r1} // F_ADRU, F_LENU (unfolded region)
|
||||
mov r7,#0xff & __NR_munmap // FIXME depends on HW and ABI of OS
|
||||
@ -132,12 +129,14 @@ __NR_close = 6 + __NR_SYSCALL_BASE
|
||||
__NR_unlink= 10 + __NR_SYSCALL_BASE
|
||||
__NR_getpid= 20 + __NR_SYSCALL_BASE
|
||||
__NR_brk = 45 + __NR_SYSCALL_BASE
|
||||
__NR_readlink=85+ __NR_SYSCALL_BASE
|
||||
__NR_readlink= 85 + __NR_SYSCALL_BASE // 0x55
|
||||
__NR_ftruncate= 93 + __NR_SYSCALL_BASE // 0x5d
|
||||
|
||||
|
||||
__NR_mmap2 = 192 + __NR_SYSCALL_BASE
|
||||
__NR_mprotect = 125 + __NR_SYSCALL_BASE
|
||||
__NR_munmap = 91 + __NR_SYSCALL_BASE
|
||||
__NR_memfd_create= 0x181 + __NR_SYSCALL_BASE // 385
|
||||
__NR_mmap2 = 192 + __NR_SYSCALL_BASE // 0xc0
|
||||
__NR_mprotect = 125 + __NR_SYSCALL_BASE // 0x7d
|
||||
__NR_munmap = 91 + __NR_SYSCALL_BASE // 0x5b
|
||||
|
||||
__ARM_NR_BASE = 0x0f0000 + __NR_SYSCALL_BASE
|
||||
__ARM_NR_cacheflush = 2 + __ARM_NR_BASE
|
||||
@ -187,6 +186,12 @@ readlink:
|
||||
munmap:
|
||||
do_sys __NR_munmap; ret
|
||||
|
||||
ftruncate: .globl ftruncate
|
||||
do_sys __NR_ftruncate; ret
|
||||
|
||||
memfd_create: .globl memfd_create
|
||||
do_sys7t2 __NR_memfd_create; ret
|
||||
|
||||
// Sometimes Linux enforces page-aligned address
|
||||
Pprotect: .globl Pprotect
|
||||
mprotect: .globl mprotect
|
||||
|
||||
@ -101,14 +101,10 @@ F_ADRU= 0 * NBPW
|
||||
F_LENU= 1 * NBPW
|
||||
F_ARGC= 2 * NBPW
|
||||
|
||||
old_sp .req x15
|
||||
foldi .req x14
|
||||
u_ptr .req x12
|
||||
mfd .req w11
|
||||
bl L70
|
||||
L70_ret:
|
||||
mov foldi,lr
|
||||
|
||||
foldi .req lr
|
||||
old_sp .req x14 // busy: lr,x14
|
||||
mov old_sp,sp
|
||||
ldr w0,[foldi,#sz_unc]
|
||||
str x0,[old_sp,#F_LENU]
|
||||
@ -119,16 +115,19 @@ L70_ret:
|
||||
mov arg3,sp // dst for decompress
|
||||
ldr arg2w,[foldi,#sz_cpr] // srclen
|
||||
add arg1,foldi,#sz_b_info // src
|
||||
.unreq foldi // busy: x14
|
||||
bl f_decompress
|
||||
|
||||
mov arg2w,#0
|
||||
adr arg1,str_upx
|
||||
mfd .req w15 // busy: x15,x14
|
||||
do_sys __NR_memfd_create; mov mfd, w0
|
||||
|
||||
mov arg2,sp
|
||||
ldr arg3,[old_sp,#F_LENU]
|
||||
do_sys __NR_write
|
||||
mov sp,old_sp // de-alloca
|
||||
.unreq old_sp // busy: x15
|
||||
|
||||
mov arg6,#0 // beginning of file
|
||||
mov arg5w,mfd
|
||||
@ -137,14 +136,17 @@ L70_ret:
|
||||
ldr arg2,[sp,#F_LENU]
|
||||
mov arg1,#0 // addr (kernel chooses)
|
||||
do_sys __NR_mmap; str x0,[sp,#F_ADRU]
|
||||
u_ptr .req x14 // busy: x15,x14
|
||||
mov u_ptr,x0
|
||||
|
||||
mov arg1w,mfd
|
||||
.unreq mfd // busy: x14
|
||||
do_sys __NR_close
|
||||
|
||||
adr arg1,_start - 4*4 // &SO_INFO
|
||||
add arg2,sp,#F_ARGC // &{argc, argv, envp}
|
||||
br u_ptr
|
||||
.unreq u_ptr
|
||||
|
||||
str_upx:
|
||||
.asciz "upx"
|
||||
|
||||
@ -435,7 +435,7 @@ get_PAGE_MASK(void)
|
||||
unsigned
|
||||
get_PAGE_MASK(void) // the mask which KEEPS the page address
|
||||
{
|
||||
int fd = open("/proc/self/auxv", O_RDONLY, 0);
|
||||
int fd = open(addr_string("/proc/self/auxv"), O_RDONLY, 0);
|
||||
Elf32_auxv_t data[40];
|
||||
Elf32_auxv_t *end = &data[read(fd, data, sizeof(data)) / sizeof(data[0])];
|
||||
close(fd);
|
||||
@ -617,6 +617,7 @@ upx_so_main( // returns &escape_hatch
|
||||
// prevent the mmap(0, ...) from stealing that address range.
|
||||
munmap(x1.buf, x1.size); // Discard original page frames in RAM.
|
||||
x1.buf = mfd_addr; // will add pfx soon
|
||||
DPRINTF("mfd_addr= %%p\\n", mfd_addr);
|
||||
}
|
||||
else {
|
||||
underlay(x1.size, x1.buf, pfx, phdr->p_flags); // also makes PROT_WRITE
|
||||
|
||||
Loading…
Reference in New Issue
Block a user