diff options
-rw-r--r-- | src/user/app/httpd/httpd.c | 9 | ||||
-rw-r--r-- | src/user/lib/_start2.c | 17 | ||||
-rw-r--r-- | src/user/lib/elfload.c | 46 | ||||
-rw-r--r-- | src/user/lib/err.c | 36 | ||||
-rw-r--r-- | src/user/lib/include/err.h | 8 | ||||
-rw-r--r-- | src/user/lib/include/stdlib.h | 3 | ||||
-rw-r--r-- | src/user/lib/stdlib.c | 8 |
7 files changed, 99 insertions, 28 deletions
diff --git a/src/user/app/httpd/httpd.c b/src/user/app/httpd/httpd.c index 2ffc2ba..02f9e6b 100644 --- a/src/user/app/httpd/httpd.c +++ b/src/user/app/httpd/httpd.c @@ -2,12 +2,11 @@ * easily DoSable (like the rest of the network stack), vulnerable to path traversal, etc */ #include <camellia/flags.h> #include <camellia/syscalls.h> +#include <err.h> #include <stdio.h> #include <string.h> #include <unistd.h> -#define eprintf(fmt, ...) fprintf(stderr, "httpd: "fmt"\n" __VA_OPT__(,) __VA_ARGS__) - static void handle(FILE *c) { char buf[2048]; fgets(buf, sizeof buf, c); @@ -69,10 +68,8 @@ int main(int argc, char **argv) { handle_t conn; for (;;) { conn = _syscall_open(path, strlen(path), OPEN_RW); - if (conn < 0) { - eprintf("open('%s') failed, %d", path, conn); - return 1; - } + if (conn < 0) + errx(1, "open('%s') failed, errno %d", path, -conn); FILE *f = fdopen(conn, "a+"); handle(f); fclose(f); diff --git a/src/user/lib/_start2.c b/src/user/lib/_start2.c index 6d1431f..0582dde 100644 --- a/src/user/lib/_start2.c +++ b/src/user/lib/_start2.c @@ -1,13 +1,30 @@ #include <camellia/syscalls.h> #include <stdio.h> #include <stdlib.h> +#include <string.h> #include <unistd.h> #include <user/lib/elfload.h> int main(int argc, char **argv, char **envp); +__attribute__((visibility("hidden"))) +extern char _image_base[]; + +const char *shortname(const char *path) { + if (!path) return "unknown program"; + const char *slash = strrchr(path, '/'); + if (slash) return slash + 1; + return path; +} + _Noreturn void _start2(struct execdata *ed) { + const char *progname; elf_selfreloc(); __setinitialcwd(ed->cwd); + + progname = shortname(ed->argv[0]); + setprogname(progname); + _klogf("_start2 %s 0x%x", progname, _image_base); + exit(main(ed->argc, ed->argv, ed->envp)); } diff --git a/src/user/lib/elfload.c b/src/user/lib/elfload.c index 9776a13..99633d1 100644 --- a/src/user/lib/elfload.c +++ b/src/user/lib/elfload.c @@ -71,6 +71,8 @@ static void *memdup(const void *orig, size_t len) { return n; } +static const char *default_argv[] = {NULL}; + /* 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, const char **argv, char **envp, void *stack); // elfload.s @@ -78,30 +80,30 @@ _Noreturn void execbuf_chstack(void *stack, void __user *buf, size_t len); void _freejmp(void *entry, void *low, size_t imglen, const char **argv, char **envp) { void *stack = (void*)~0; struct execdata ed; + size_t argv_len; - if (argv) { - size_t argv_len; - ed.argc = 0; - while (argv[ed.argc]) ed.argc++; - argv_len = (ed.argc+1) * sizeof(char *); - - /* make a copy of argv, so it doesn't get overridden - * if it overlaps with the new stack. */ - argv = memdup(argv, argv_len); - for (int i = 0; i < ed.argc; i++) - argv[i] = strdup(argv[i]); - - stack -= argv_len; - ed.argv = stack; - - for (int i = 0; i < ed.argc; i++) { - size_t len = strlen(argv[i]) + 1; - stack -= len; - memcpy(stack, argv[i], len); - ed.argv[i] = stack; - } - ed.argv[ed.argc] = NULL; + if (!argv) argv = default_argv; + + ed.argc = 0; + while (argv[ed.argc]) ed.argc++; + argv_len = (ed.argc+1) * sizeof(char *); + + /* make a copy of argv, so it doesn't get overridden + * if it overlaps with the new stack. */ + argv = memdup(argv, argv_len); + for (int i = 0; i < ed.argc; i++) + argv[i] = strdup(argv[i]); + + stack -= argv_len; + ed.argv = stack; + + for (int i = 0; i < ed.argc; i++) { + size_t len = strlen(argv[i]) + 1; + stack -= len; + memcpy(stack, argv[i], len); + ed.argv[i] = stack; } + ed.argv[ed.argc] = NULL; /* push cwd */ size_t len = absolutepath(NULL, NULL, 0); diff --git a/src/user/lib/err.c b/src/user/lib/err.c new file mode 100644 index 0000000..7684b6d --- /dev/null +++ b/src/user/lib/err.c @@ -0,0 +1,36 @@ +#include <err.h> +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +_Noreturn void err(int ret, const char *fmt, ...) { + va_list args; + va_start(args, fmt); + vwarn(fmt, args); + va_end(args); + exit(ret); +} + +_Noreturn void errx(int ret, const char *fmt, ...) { + va_list args; + va_start(args, fmt); + vwarnx(fmt, args); + va_end(args); + exit(ret); +} + +void vwarn(const char *fmt, va_list args) { + fprintf(stderr, "%s: ", getprogname()); + if (fmt) { + vfprintf(stderr, fmt, args); + fprintf(stderr, ": "); + } + fprintf(stderr, "%s\n", strerror(errno)); +} + +void vwarnx(const char *fmt, va_list args) { + fprintf(stderr, "%s: ", getprogname()); + if (fmt) vfprintf(stderr, fmt, args); + fprintf(stderr, "\n"); +} diff --git a/src/user/lib/include/err.h b/src/user/lib/include/err.h index e69de29..9ce4253 100644 --- a/src/user/lib/include/err.h +++ b/src/user/lib/include/err.h @@ -0,0 +1,8 @@ +#pragma once +#include <stdarg.h> + +_Noreturn void err(int ret, const char *fmt, ...); +_Noreturn void errx(int ret, const char *fmt, ...); + +void vwarn(const char *fmt, va_list args); +void vwarnx(const char *fmt, va_list args); diff --git a/src/user/lib/include/stdlib.h b/src/user/lib/include/stdlib.h index 2df0bf7..8a86265 100644 --- a/src/user/lib/include/stdlib.h +++ b/src/user/lib/include/stdlib.h @@ -12,6 +12,9 @@ _Noreturn void abort(void); _Noreturn void exit(int); +const char *getprogname(void); +void setprogname(const char *progname); + int mkstemp(char *template); char *getenv(const char *name); int system(const char *cmd); diff --git a/src/user/lib/stdlib.c b/src/user/lib/stdlib.c index ffa9f15..5d1b09f 100644 --- a/src/user/lib/stdlib.c +++ b/src/user/lib/stdlib.c @@ -8,6 +8,14 @@ _Noreturn void abort(void) { _syscall_exit(1); } +static const char *progname; +const char *getprogname(void) { + return progname; +} +void setprogname(const char *pg) { + progname = pg; +} + int mkstemp(char *template) { // TODO randomize template handle_t h = camellia_open(template, OPEN_CREATE | OPEN_RW); |