summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/user/app/testelf/main.c13
-rw-r--r--src/user/lib/elfload.c35
2 files changed, 39 insertions, 9 deletions
diff --git a/src/user/app/testelf/main.c b/src/user/app/testelf/main.c
index ee7465b..ea97b4a 100644
--- a/src/user/app/testelf/main.c
+++ b/src/user/app/testelf/main.c
@@ -1,4 +1,6 @@
#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
const char *str = "Hello!", *str2 = "World.";
@@ -8,5 +10,16 @@ int main(int argc, char **argv) {
printf("argc == %u\n", argc);
for (int i = 0; i < argc; i++)
printf("argv[%u] == 0x%x == \"%s\"\n", i, argv[i], argv[i]);
+ if (strcmp(argv[1], "stackexec") == 0) {
+ /* exec something with arguments on the stack */
+ const char s_d[] = "I am a pretty long string on the stack. Oh my. " \
+ "I hope I won't get corrupted.\0";
+ char s[sizeof(s_d)];
+ memcpy(s, s_d, sizeof(s_d));
+ const char *argv2[] = {argv[0], s, s, "hello", s, s, s, "lol", NULL};
+ printf("argv2 == 0x%x, s == 0x%x\n== exec ==\n", argv2, s);
+ execv(argv[0], (void*)argv2);
+ puts("stackexec failed");
+ }
return 0;
}
diff --git a/src/user/lib/elfload.c b/src/user/lib/elfload.c
index 4fcc1db..6912239 100644
--- a/src/user/lib/elfload.c
+++ b/src/user/lib/elfload.c
@@ -65,16 +65,36 @@ static size_t elf_spread(const void *elf) {
return high - low;
}
+static void *malloccpy(const void *orig, size_t len) {
+ void *n = malloc(len);
+ memcpy(n, orig, len);
+ return n;
+}
+
/* frees memory outside of [low; low + len] and jumps to *entry
* also sets up main's stack */
-void _freejmp_chstack(void *entry, void *low, size_t len, char **argv, char **envp, void *stack); // elfload.s
+void _freejmp_chstack(void *entry, void *low, size_t len, const char **argv, char **envp, void *stack); // elfload.s
_Noreturn void execbuf_chstack(void *stack, void __user *buf, size_t len);
-void _freejmp(void *entry, void *low, size_t imglen, char **argv, char **envp) {
+void _freejmp(void *entry, void *low, size_t imglen, const char **argv, char **envp) {
size_t len;
union {void *b; void **ptr; uintptr_t *n;} stack;
stack.b = (void*)~0; /* default stack location */
+ void *stack_start = stack.b - 0x1000;
void *cwd;
+ /* copy argv off the stack */
+ int argc = 0;
+ size_t argv_len;
+ if (argv) {
+ while (argv[argc]) argc++;
+ argv_len = argc * sizeof(char *);
+ if ((void*)argv > stack_start)
+ argv = malloccpy(argv, argv_len);
+ for (int i = 0; argv[i]; i++)
+ if ((void*)argv[i] > stack_start)
+ argv[i] = malloccpy(argv[i], strlen(argv[i]) + 1);
+ }
+
/* push cwd */
len = absolutepath(NULL, NULL, 0);
stack.b -= len;
@@ -82,19 +102,16 @@ void _freejmp(void *entry, void *low, size_t imglen, char **argv, char **envp) {
getcwd(cwd, len);
/* push argv */
- int argc = 0;
if (argv) {
- for (int i = 0; argv[i]; i++) {
+ for (int i = 0; i < argc; i++) {
len = strlen(argv[i]) + 1;
stack.b -= len;
memcpy(stack.b, argv[i], len);
argv[i] = stack.b;
- argc++;
}
- len = sizeof(char*) * argc;
*--(stack.ptr) = NULL; /* NULL terminate argv */
- stack.b -= len;
- memcpy(stack.b, argv, len);
+ stack.b -= argv_len;
+ memcpy(stack.b, argv, argv_len);
argv = stack.b;
}
@@ -147,7 +164,7 @@ void elf_exec(void *base, char **argv, char **envp) {
void *newstack = _syscall_memflag((void*)0x1000, 0x1000, MEMFLAG_FINDFREE | MEMFLAG_PRESENT);
if (!newstack) return;
- _freejmp_chstack(exebase + ehdr->e_entry, exebase, elf_spread(ehdr) + 0x1000, argv, envp, newstack);
+ _freejmp_chstack(exebase + ehdr->e_entry, exebase, elf_spread(ehdr) + 0x1000, (const char**)argv, envp, newstack);
}
void *elf_partialexec(void *base) {