Skip to content

Commit 7a01350

Browse files
author
Po Lu
committed
Replace AT_EXECFN in auxiliary vectors of programs executed on Android
* exec/exec.c (insert_args, exec_0): On non-MIPS systems, copy NAME and its length to the loader area. State that MIPS support is not yet available (though it will be pending the availability of a functioning emulator). * exec/loader-aarch64.s (_start): * exec/loader-armeabi.s (_start): * exec/loader-x86.s (_start): * exec/loader-x86_64.s (_start): Displace auxv, environ, and argv to create sufficient space for the provided file name, and copy the file name there. Replace AT_EXECFN to refer to this space.
1 parent f5b59a8 commit 7a01350

File tree

6 files changed

+636
-325
lines changed

6 files changed

+636
-325
lines changed

exec/exec.c

+24-1
Original file line numberDiff line numberDiff line change
@@ -831,7 +831,7 @@ insert_args (struct exec_tracee *tracee, USER_REGS_STRUCT *regs,
831831
assert (new3 == new + effective_size);
832832

833833
/* And that it is properly aligned. */
834-
assert (!(new3 & (sizeof new3 - 2)));
834+
assert (!(new3 & (sizeof new3 - 1)));
835835

836836
/* Now modify the system call argument to point to new +
837837
text_size. */
@@ -916,6 +916,9 @@ exec_0 (char *name, struct exec_tracee *tracee,
916916
program_header program;
917917
USER_WORD entry, program_entry, offset;
918918
USER_WORD header_offset;
919+
#ifndef __mips__
920+
USER_WORD name_len, aligned_len;
921+
#endif /* !__mips__ */
919922
struct exec_jump_command jump;
920923
#if defined __mips__ && !defined MIPS_NABI
921924
int fpu_mode;
@@ -1146,6 +1149,26 @@ exec_0 (char *name, struct exec_tracee *tracee,
11461149
sizeof jump);
11471150
loader_area_used += sizeof jump;
11481151

1152+
/* TODO: MIPS support. */
1153+
#ifndef __mips__
1154+
/* Copy the length of NAME and NAME itself to the loader area. */
1155+
name_len = strlen (name);
1156+
aligned_len = ((name_len + 1 + sizeof name_len - 1)
1157+
& -sizeof name_len);
1158+
if (sizeof loader_area - loader_area_used
1159+
< aligned_len + sizeof name_len)
1160+
goto fail1;
1161+
memcpy (loader_area + loader_area_used, &name_len, sizeof name_len);
1162+
loader_area_used += sizeof name_len;
1163+
memcpy (loader_area + loader_area_used, name, name_len + 1);
1164+
loader_area_used += name_len + 1;
1165+
1166+
/* Properly align the loader area. */
1167+
offset = aligned_len - (name_len + 1);
1168+
while (offset--)
1169+
loader_area[loader_area_used++] = '\0';
1170+
#endif /* !__mips__ */
1171+
11491172
/* Close the file descriptor and return the number of bytes
11501173
used. */
11511174

exec/loader-aarch64.s

+127-85
Original file line numberDiff line numberDiff line change
@@ -22,88 +22,88 @@
2222
.section .text
2323
.global _start
2424
_start:
25-
//mov x8, 101 // SYS_nanosleep
26-
//adr x0, timespec // req
27-
//mov x1, #0 // rem
28-
//svc #0 // syscall
25+
// mov x8, 101 // SYS_nanosleep
26+
// adr x0, timespec // req
27+
// mov x1, #0 // rem
28+
// svc #0 // syscall
2929
mov x20, sp // x20 = sp
3030
ldr x10, [x20] // x10 = original SP
3131
add x20, x20, #16 // x20 = start of load area
3232
mov x28, #-1 // x28 = secondary fd
33-
.next_action:
33+
next_action:
3434
ldr x11, [x20] // action number
3535
and x12, x11, #-17 // actual action number
36-
cbz x12, .open_file // open file?
36+
cbz x12, open_file // open file?
3737
cmp x12, #3 // jump?
38-
beq .rest_of_exec
38+
beq rest_of_exec
3939
cmp x12, #4 // anonymous mmap?
40-
beq .do_mmap_anon
41-
.do_mmap:
40+
beq do_mmap_anon
41+
do_mmap:
4242
ldr x0, [x20, 8] // vm_address
4343
ldr x1, [x20, 32] // length
4444
ldr x2, [x20, 24] // protection
4545
ldr x3, [x20, 40] // flags
4646
tst x11, #16 // primary fd?
4747
mov x4, x29 // primary fd
48-
beq .do_mmap_1
48+
beq do_mmap_1
4949
mov x4, x28 // secondary fd
50-
.do_mmap_1:
50+
do_mmap_1:
5151
mov x8, #222 // SYS_mmap
5252
ldr x5, [x20, 16] // file_offset
5353
svc #0 // syscall
5454
ldr x9, [x20, 8] // length
5555
cmp x0, x9 // mmap result
56-
bne .perror // print error
56+
bne perror // print error
5757
ldr x3, [x20, 48] // clear
5858
add x1, x1, x0 // x1 = vm_address + end
5959
sub x3, x1, x3 // x3 = x1 - clear
6060
mov x0, #0 // x0 = 0
61-
.fill64:
61+
fill64:
6262
sub x2, x1, x3 // x2 = x1 - x3
6363
cmp x2, #63 // x2 >= 64?
64-
ble .fillb // start filling bytes
64+
ble fillb // start filling bytes
6565
stp x0, x0, [x3] // x3[0] = 0, x3[1] = 0
6666
stp x0, x0, [x3, 16] // x3[2] = 0, x3[3] = 0
6767
stp x0, x0, [x3, 32] // x3[4] = 0, x3[5] = 0
6868
stp x0, x0, [x3, 48] // x3[6] = 0, x3[7] = 0
6969
add x3, x3, #64 // x3 += 8
70-
b .fill64
71-
.fillb:
70+
b fill64
71+
fillb:
7272
cmp x1, x3 // x1 == x3?
73-
beq .continue // done
73+
beq continue // done
7474
strb w0, [x3], #1 // ((char *) x3)++ = 0
75-
b .fillb
76-
.continue:
75+
b fillb
76+
continue:
7777
add x20, x20, #56 // next action
78-
b .next_action
79-
.do_mmap_anon:
78+
b next_action
79+
do_mmap_anon:
8080
ldr x0, [x20, 8] // vm_address
8181
ldr x1, [x20, 32] // length
8282
ldr x2, [x20, 24] // protection
8383
ldr x3, [x20, 40] // flags
8484
mov x4, #-1 // fd
85-
b .do_mmap_1
86-
.open_file:
85+
b do_mmap_1
86+
open_file:
8787
mov x8, #56 // SYS_openat
8888
mov x0, #-100 // AT_FDCWD
8989
add x1, x20, #8 // file name
9090
mov x2, #0 // O_RDONLY
9191
mov x3, #0 // mode
9292
svc #0 // syscall
9393
cmp x0, #-1 // rc < 0?
94-
ble .perror
94+
ble perror
9595
mov x19, x1 // x19 == x1
96-
.nextc:
96+
nextc:
9797
ldrb w2, [x1], #1 // b = *x1++
9898
cmp w2, #47 // dir separator?
99-
bne .nextc1 // not dir separator
99+
bne nextc1 // not dir separator
100100
mov x19, x1 // x19 = char past separator
101-
.nextc1:
102-
cbnz w2, .nextc // b?
101+
nextc1:
102+
cbnz w2, nextc // b?
103103
add x1, x1, #7 // round up x1
104104
and x20, x1, #-8 // mask for round, set x20
105105
tst x11, #16 // primary fd?
106-
bne .secondary // secondary fd
106+
bne secondary // secondary fd
107107
mov x29, x0 // primary fd
108108
mov x8, #167 // SYS_prctl
109109
mov x0, #15 // PR_SET_NAME
@@ -113,75 +113,117 @@ _start:
113113
mov x4, #0 // arg4
114114
mov x5, #0 // arg5
115115
svc #0 // syscall
116-
b .next_action // next action
117-
.secondary:
116+
b next_action // next action
117+
secondary:
118118
mov x28, x0 // secondary fd
119-
b .next_action // next action.
120-
.perror:
119+
b next_action // next action.
120+
perror:
121121
mov x8, #93 // SYS_exit
122122
mvn x0, x0 // x1 = ~x0
123123
add x0, x0, 1 // x1 += 1
124124
svc #0 // exit
125-
.rest_of_exec:
125+
rest_of_exec:
126126
mov x7, x20 // x7 = x20
127-
mov x20, x10 // x20 = x10
128-
ldr x9, [x20] // argc
129-
add x9, x9, #2 // x9 += 2
127+
mov x8, x10 // x8 = x10
128+
ldr x9, [x8], #16 // (void *) x8 += 2
130129
lsl x9, x9, #3 // argc * 8
131-
add x20, x20, x9 // now past argv
132-
.skipenv:
133-
ldr x9, [x20], #8 // x9 = *envp++
134-
cbnz x9, .skipenv // x9?
135-
.one_auxv:
136-
ldr x9, [x20], #16 // x9 = *sp, sp += 2
137-
cbz x9, .cleanup // !x9?
138-
cmp x9, #3 // is AT_PHDR?
139-
beq .replace_phdr // replace
140-
cmp x9, #4 // is AT_PHENT?
141-
beq .replace_phent // replace
142-
cmp x9, #5 // is AT_PHNUM?
143-
beq .replace_phnum // replace
144-
cmp x9, #9 // is AT_ENTRY?
145-
beq .replace_entry // replace
146-
cmp x9, #7 // is AT_BASE?
147-
beq .replace_base // replace
148-
b .one_auxv // next auxv
149-
.replace_phdr:
150-
ldr x9, [x7, 40] // at_phdr
151-
str x9, [x20, -8] // store value
152-
b .one_auxv
153-
.replace_phent:
154-
ldr x9, [x7, 24] // at_phent
155-
str x9, [x20, -8] // store value
156-
b .one_auxv
157-
.replace_phnum:
158-
ldr x9, [x7, 32] // at_phnum
159-
str x9, [x20, -8] // store value
160-
b .one_auxv
161-
.replace_entry:
162-
ldr x9, [x7, 16] // at_entry
163-
str x9, [x20, -8] // store value
164-
b .one_auxv
165-
.replace_base:
166-
ldr x9, [x7, 48] // at_base
167-
str x9, [x20, -8] // store value
168-
b .one_auxv
169-
.cleanup:
170-
cmp x28, #-1 // is secondary fd set?
171-
bne .cleanup1 // not set
130+
add x8, x8, x9 // now past argv
131+
skip_environ:
132+
ldr x9, [x8], #8 // x9 = *envp++
133+
cbnz x9, skip_environ // x9?
134+
// Skip the auxiliary vector.
135+
1: ldp x11, x12, [x8], #16 // a_type, a_un.a_val
136+
cbnz x11, 1b // a_type != NULL
137+
// Prepare sufficient space at x20 for the file name string.
138+
// Load the aforesaid string, and its length.
139+
ldr x6, [x7, 56] // string length
140+
add x6, x6, 1
141+
add x5, x7, 64 // string pointer
142+
sub x4, x10, x8 // number of elements to copy
143+
sub x7, x8, x6 // AT_EXECFN location
144+
and x7, x7, -8 // align value
145+
add x4, x7, x4 // destination argc
146+
and x4, x4, -16 // align destination argc
147+
// Load values that must be into registers x14-x19.
148+
// x14 = cmd->entry
149+
// x15 = cmd->at_entry
150+
// x16 = cmd->at_phent
151+
// x17 = cmd->at_phnum
152+
// x18 = cmd->at_phdr
153+
// x19 = cmd->at_base
154+
ldp x14, x15, [x20, 8]
155+
ldp x16, x17, [x20, 24]
156+
ldp x18, x19, [x20, 40]
157+
// Move the string to a safe location, if necessary.
158+
sub x3, x4, x5 // distance from dest to string
159+
cmp x3, x6 // distance > length
160+
bge copy_env_and_args // not necessary
161+
mov x2, x5 // src
162+
sub x5, x4, x6 // backup string
163+
mov x1, x5 // dst
164+
add x9, x2, x6 // src end
165+
cmp x2, x9
166+
bcs copy_env_and_args
167+
1: ldrb w3, [x2], #1
168+
strb w3, [x1], #1
169+
cmp x2, x9
170+
bls 1b
171+
copy_env_and_args:
172+
// Copy argc and the environment array.
173+
mov x8, x10
174+
mov x10, x4
175+
1: ldr x9, [x8], #8 // envp
176+
str x9, [x4], #8
177+
cbnz x9, 1b
178+
1: ldr x9, [x8], #8 // environ
179+
str x9, [x4], #8
180+
cbnz x9, 1b
181+
copy_auxv:
182+
ldp x11, x12, [x8], #16 // a_type, a_un.a_val
183+
stp x11, x12, [x4], #16 // write value
184+
cbz x11, cleanup // AT_NULL
185+
cmp x11, #3 // AT_PHDR
186+
csel x12, x18, x12, eq
187+
cmp x11, #4 // AT_PHENT
188+
csel x12, x16, x12, eq
189+
cmp x11, #5 // AT_PHNUM
190+
csel x12, x17, x12, eq
191+
cmp x11, #9 // AT_ENTRY
192+
csel x12, x15, x12, eq
193+
cmp x11, #7 // AT_BASE
194+
csel x12, x19, x12, eq
195+
cmp x11, #31 // AT_EXECFN
196+
csel x12, x7, x12, eq
197+
str x12, [x4, -8] // replace value
198+
b copy_auxv
199+
cleanup:
200+
// Copy the filename.
201+
add x9, x5, x6 // end
202+
cmp x5, x9
203+
bcs 2f
204+
1: ldrb w3, [x5], #1
205+
strb w3, [x7], #1
206+
cmp x5, x9
207+
bls 1b
208+
// Close file descriptors.
209+
2: cmp x28, #-1 // is secondary fd set?
210+
beq cleanup1 // not set
172211
mov x8, #57 // SYS_close
173212
mov x0, x28 // secondary fd
174213
svc #0 // syscall
175-
.cleanup1:
214+
cleanup1:
176215
mov x8, #57 // SYS_close
177216
mov x0, x29 // primary fd
178217
svc #0 // syscall
179-
.enter:
218+
enter:
180219
mov sp, x10 // restore original SP
181220
mov x0, #0 // clear rtld_fini
182-
ldr x1, [x7, 8] // branch to code
183-
br x1
221+
br x14
184222

185-
timespec:
186-
.quad 10
187-
.quad 10
223+
// timespec:
224+
// .quad 10
225+
// .quad 10
226+
227+
// Local Variables:
228+
// asm-comment-char: ?/
229+
// End:

0 commit comments

Comments
 (0)