summaryrefslogtreecommitdiff
path: root/exec
diff options
context:
space:
mode:
authorPo Lu <luangruo@yahoo.com>2023-05-31 11:27:19 +0800
committerPo Lu <luangruo@yahoo.com>2023-05-31 11:27:19 +0800
commit456095ed3129f7ce2fe1ff019ea5d912a69ed2a1 (patch)
tree083ed74ffb0e862c8733262710dd589c349834d8 /exec
parent8db957366448b6cc09462e295bed9a079426519f (diff)
downloademacs-456095ed3129f7ce2fe1ff019ea5d912a69ed2a1.tar.gz
Update Android port
* exec/exec.c (insert_args): New argument `arg3'. Replace argv[1] with that argument. (exec_0): Pass file name of script to `insert_args'.
Diffstat (limited to 'exec')
-rw-r--r--exec/exec.c93
1 files changed, 63 insertions, 30 deletions
diff --git a/exec/exec.c b/exec/exec.c
index 0e077284860..0d9187cabfa 100644
--- a/exec/exec.c
+++ b/exec/exec.c
@@ -740,16 +740,18 @@ process_program_header (const char *name, int fd,
}
/* Prepend one or two extra arguments ARG1 and ARG2 to a pending
- execve system call. TRACEE is the tracee performing the system
- call, and REGS are its current user registers. Value is 1 upon
- failure, else 0. */
+ execve system call. Replace the argument immediately after
+ with ARG3.
+
+ TRACEE is the tracee performing the system call, and REGS are its
+ current user registers. Value is 1 upon failure, else 0. */
static int
insert_args (struct exec_tracee *tracee, USER_REGS_STRUCT *regs,
- const char *arg1, const char *arg2)
+ const char *arg1, const char *arg2, const char *arg3)
{
USER_WORD argv, argc, word, new;
- USER_WORD new1, new2;
+ USER_WORD new1, new2, new3, i;
size_t text_size, effective_size;
USER_REGS_STRUCT original;
@@ -783,15 +785,17 @@ insert_args (struct exec_tracee *tracee, USER_REGS_STRUCT *regs,
text. */
text_size = (strlen (arg1) + 1
- + (arg2 ? strlen (arg2) + 1 : 0));
+ + (arg2 ? strlen (arg2) + 1 : 0)
+ + strlen (arg3) + 1);
/* Round it up to the user word size. */
text_size += sizeof (USER_WORD) - 1;
text_size &= ~(sizeof (USER_WORD) - 1);
- /* Now allocate the new argv. */
+ /* Now allocate the new argv. Make sure argc is at least 1; it
+ needs to hold ARG3. */
- effective_size = sizeof word * (argc + 2) + text_size;
+ effective_size = sizeof word * (MAX (1, argc) + 2) + text_size;
if (arg2)
effective_size += sizeof word;
@@ -808,11 +812,13 @@ insert_args (struct exec_tracee *tracee, USER_REGS_STRUCT *regs,
/* Figure out where argv starts. */
- new2 = new + text_size;
+ new3 = new + text_size;
- /* Now write the two strings. */
+ /* Now write the first two strings. */
new1 = new + strlen (arg1) + 1;
+ new2 = new1 + (arg2 ? strlen (arg2) + 1 : 0);
+
if (user_copy (tracee, (const unsigned char *) arg1,
new, new1 - new))
goto fail;
@@ -821,50 +827,77 @@ insert_args (struct exec_tracee *tracee, USER_REGS_STRUCT *regs,
new1, new2 - new1))
goto fail;
+ /* Write the replacement arg3, the file name of the executable. */
+
+ if (user_copy (tracee, (const unsigned char *) arg3,
+ new2, new3 - new2))
+ goto fail;
+
/* Start copying argv back to new2. First, write the one or two new
arguments. */
if (ptrace (PTRACE_POKETEXT, tracee->pid,
- (void *) new2, (void *) new))
+ (void *) new3, (void *) new))
goto fail;
- new2 += sizeof new2;
+ new3 += sizeof new3;
if (arg2 && ptrace (PTRACE_POKETEXT, tracee->pid,
- (void *) new2, (void *) new1))
+ (void *) new3, (void *) new1))
goto fail;
else if (arg2)
- new2 += sizeof new2;
+ new3 += sizeof new3;
+
+ /* Next, write the third argument. */
+
+ if (ptrace (PTRACE_POKETEXT, tracee->pid, (void *) new3,
+ (void *) new2))
+ goto fail;
+
+ new3 += sizeof new3;
/* Copy the remaining arguments back. */
argv = regs->SYSCALL_ARG1_REG;
- /* Make sure the trailing NULL is included. */
- argc += 1;
-
- while (argc)
+ if (argc)
{
- /* Read one argument. */
- word = ptrace (PTRACE_PEEKDATA, tracee->pid,
- (void *) argv, NULL);
- argv += sizeof argv;
- argc--;
+ /* Make sure the trailing NULL is included. */
+ argc += 1;
+
+ /* Now copy each argument in argv, starting from argv[1]. */
+
+ for (i = 1; i < argc; ++i)
+ {
+ /* Read one argument. */
+ word = ptrace (PTRACE_PEEKDATA, tracee->pid,
+ (void *) (argv + i * sizeof argv), NULL);
+
+ /* Write one argument, then increment new3. */
- /* Write one argument, then increment new2. */
+ if (ptrace (PTRACE_POKETEXT, tracee->pid,
+ (void *) new3, (void *) word))
+ goto fail;
+
+ new3 += sizeof new3;
+ }
+ }
+ else
+ {
+ /* Just write the trailing NULL. */
if (ptrace (PTRACE_POKETEXT, tracee->pid,
- (void *) new2, (void *) word))
+ (void *) new3, (void *) 0))
goto fail;
- new2 += sizeof new2;
+ new3 += sizeof new3;
}
- /* Assert that new2 is not out of bounds. */
- assert (new2 == new + effective_size);
+ /* Assert that new3 is not out of bounds. */
+ assert (new3 == new + effective_size);
/* And that it is properly aligned. */
- assert (!(new2 & (sizeof new2 - 2)));
+ assert (!(new3 & (sizeof new3 - 2)));
/* Now modify the system call argument to point to new +
text_size. */
@@ -1046,7 +1079,7 @@ exec_0 (char *name, struct exec_tracee *tracee,
and perhaps `extra'. */
if (insert_args (tracee, regs, interpreter_name,
- extra))
+ extra, name))
goto fail1;
}