diff --git a/arch/i386/syscall_arch.h b/arch/i386/syscall_arch.h index b19f27e..838d0a2 100644 --- a/arch/i386/syscall_arch.h +++ b/arch/i386/syscall_arch.h @@ -51,25 +51,3 @@ static inline long __syscall6(long n, long a1, long a2, long a3, long a4, long a __asm__ __volatile__ ("push %6 ; call __vsyscall6 ; add $4,%%esp" : "=a"(__ret) : "a"(n), "d"(a1), "c"(a2), "D"(a3), "S"(a4), "g"(0+(long[]){a5, a6}) : "memory"); return __ret; } - - -#define __SC_socket 1 -#define __SC_bind 2 -#define __SC_connect 3 -#define __SC_listen 4 -#define __SC_accept 5 -#define __SC_getsockname 6 -#define __SC_getpeername 7 -#define __SC_socketpair 8 -#define __SC_send 9 -#define __SC_recv 10 -#define __SC_sendto 11 -#define __SC_recvfrom 12 -#define __SC_shutdown 13 -#define __SC_setsockopt 14 -#define __SC_getsockopt 15 -#define __SC_sendmsg 16 -#define __SC_recvmsg 17 -#define __SC_accept4 18 -#define __SC_recvmmsg 19 -#define __SC_sendmmsg 20 diff --git a/arch/powerpc/syscall_arch.h b/arch/powerpc/syscall_arch.h index 21c1134..7a6b6b7 100644 --- a/arch/powerpc/syscall_arch.h +++ b/arch/powerpc/syscall_arch.h @@ -39,21 +39,3 @@ static inline long __syscall6(long n, long a, long b, long c, long d, long e, lo { return (__syscall)(n, a, b, c, d, e, f); } - -#define __SC_socket 1 -#define __SC_bind 2 -#define __SC_connect 3 -#define __SC_listen 4 -#define __SC_accept 5 -#define __SC_getsockname 6 -#define __SC_getpeername 7 -#define __SC_socketpair 8 -#define __SC_send 9 -#define __SC_recv 10 -#define __SC_sendto 11 -#define __SC_recvfrom 12 -#define __SC_shutdown 13 -#define __SC_setsockopt 14 -#define __SC_getsockopt 15 -#define __SC_sendmsg 16 -#define __SC_recvmsg 17 diff --git a/include/unistd.h b/include/unistd.h index bf10a6d..a906552 100644 --- a/include/unistd.h +++ b/include/unistd.h @@ -177,6 +177,7 @@ void endusershell(void); char *getusershell(void); int acct(const char *); long syscall(long, ...); +int execvpe(const char *, char *const [], char *const []); #endif #ifdef _GNU_SOURCE diff --git a/src/env/__init_security.c b/src/env/__init_security.c deleted file mode 100644 index da5ae94..0000000 --- a/src/env/__init_security.c +++ /dev/null @@ -1,28 +0,0 @@ -#include -#include -#include -#include "syscall.h" -#include "libc.h" -#include "atomic.h" - -static void dummy(void *ent) -{ -} -weak_alias(dummy, __init_ssp); - -void __init_security(size_t *aux) -{ - struct pollfd pfd[3] = { {.fd=0}, {.fd=1}, {.fd=2} }; - int i; - - __init_ssp((void *)aux[AT_RANDOM]); - - if (aux[AT_UID]==aux[AT_EUID] && aux[AT_GID]==aux[AT_EGID] - && !aux[AT_SECURE]) return; - - __syscall(SYS_poll, pfd, 3, 0); - for (i=0; i<3; i++) if (pfd[i].revents&POLLNVAL) - if (__syscall(SYS_open, "/dev/null", O_RDWR|O_LARGEFILE)<0) - a_crash(); - libc.secure = 1; -} diff --git a/src/env/__libc_start_main.c b/src/env/__libc_start_main.c index ac37492..3498afb 100644 --- a/src/env/__libc_start_main.c +++ b/src/env/__libc_start_main.c @@ -1,8 +1,11 @@ #include +#include +#include +#include "syscall.h" +#include "atomic.h" #include "libc.h" void __init_tls(size_t *); -void __init_security(size_t *); #ifndef SHARED static void dummy() {} @@ -11,11 +14,17 @@ extern void (*const __init_array_start)() __attribute__((weak)); extern void (*const __init_array_end)() __attribute__((weak)); #endif +static void dummy1(void *p) {} +weak_alias(dummy1, __init_ssp); + #define AUX_CNT 38 extern size_t __hwcap, __sysinfo; extern char *__progname, *__progname_full; +#ifndef SHARED +static +#endif void __init_libc(char **envp, char *pn) { size_t i, *auxv, aux[AUX_CNT] = { 0 }; @@ -33,7 +42,17 @@ void __init_libc(char **envp, char *pn) } __init_tls(aux); - __init_security(aux); + __init_ssp((void *)aux[AT_RANDOM]); + + if (aux[AT_UID]==aux[AT_EUID] && aux[AT_GID]==aux[AT_EGID] + && !aux[AT_SECURE]) return; + + struct pollfd pfd[3] = { {.fd=0}, {.fd=1}, {.fd=2} }; + __syscall(SYS_poll, pfd, 3, 0); + for (i=0; i<3; i++) if (pfd[i].revents&POLLNVAL) + if (__syscall(SYS_open, "/dev/null", O_RDWR|O_LARGEFILE)<0) + a_crash(); + libc.secure = 1; } int __libc_start_main(int (*main)(int,char **,char **), int argc, char **argv) diff --git a/src/internal/syscall.h b/src/internal/syscall.h index dcfae00..914b0d1 100644 --- a/src/internal/syscall.h +++ b/src/internal/syscall.h @@ -164,3 +164,26 @@ long __syscall_ret(unsigned long), __syscall(syscall_arg_t, ...), #endif #endif + +/* socketcall calls */ + +#define __SC_socket 1 +#define __SC_bind 2 +#define __SC_connect 3 +#define __SC_listen 4 +#define __SC_accept 5 +#define __SC_getsockname 6 +#define __SC_getpeername 7 +#define __SC_socketpair 8 +#define __SC_send 9 +#define __SC_recv 10 +#define __SC_sendto 11 +#define __SC_recvfrom 12 +#define __SC_shutdown 13 +#define __SC_setsockopt 14 +#define __SC_getsockopt 15 +#define __SC_sendmsg 16 +#define __SC_recvmsg 17 +#define __SC_accept4 18 +#define __SC_recvmmsg 19 +#define __SC_sendmmsg 20 diff --git a/src/ldso/dynlink.c b/src/ldso/dynlink.c index 1517281..1cb3fb4 100644 --- a/src/ldso/dynlink.c +++ b/src/ldso/dynlink.c @@ -1055,12 +1055,31 @@ void *__dynlink(int argc, char **argv) size_t l = strlen(ldname); if (l >= 3 && !strcmp(ldname+l-3, "ldd")) ldd_mode = 1; *argv++ = (void *)-1; - if (argv[0] && !strcmp(argv[0], "--")) *argv++ = (void *)-1; + while (argv[0] && argv[0][0]=='-' && argv[0][1]=='-') { + char *opt = argv[0]+2; + *argv++ = (void *)-1; + if (!*opt) { + break; + } else if (!memcmp(opt, "list", 5)) { + ldd_mode = 1; + } else if (!memcmp(opt, "library-path", 12)) { + if (opt[12]=='=') env_path = opt+13; + else if (opt[12]) *argv = 0; + else if (*argv) env_path = *argv++; + } else if (!memcmp(opt, "preload", 7)) { + if (opt[7]=='=') env_preload = opt+8; + else if (opt[7]) *argv = 0; + else if (*argv) env_preload = *argv++; + } else { + argv[0] = 0; + } + argv[-1] = (void *)-1; + } if (!argv[0]) { dprintf(2, "musl libc\n" "Version %s\n" "Dynamic Program Loader\n" - "Usage: %s [--] pathname%s\n", + "Usage: %s [options] [--] pathname%s\n", __libc_get_version(), ldname, ldd_mode ? "" : " [args]"); _exit(1); diff --git a/src/process/execvp.c b/src/process/execvp.c index 0a33e42..7d32200 100644 --- a/src/process/execvp.c +++ b/src/process/execvp.c @@ -3,6 +3,7 @@ #include #include #include +#include "libc.h" extern char **__environ; @@ -47,3 +48,5 @@ int execvp(const char *file, char *const argv[]) { return __execvpe(file, argv, __environ); } + +weak_alias(__execvpe, execvpe); diff --git a/src/string/memmem.c b/src/string/memmem.c index a5a249f..3b1ae18 100644 --- a/src/string/memmem.c +++ b/src/string/memmem.c @@ -120,7 +120,7 @@ static char *twoway_memmem(const unsigned char *h, const unsigned char *z, const } /* Compare left half */ for (k=ms+1; k>mem && n[k-1] == h[k-1]; k--); - if (k == mem) return (char *)h; + if (k <= mem) return (char *)h; h += p; mem = mem0; } diff --git a/src/string/strstr.c b/src/string/strstr.c index 915c0a2..cd06912 100644 --- a/src/string/strstr.c +++ b/src/string/strstr.c @@ -130,7 +130,7 @@ static char *twoway_strstr(const unsigned char *h, const unsigned char *n) } /* Compare left half */ for (k=ms+1; k>mem && n[k-1] == h[k-1]; k--); - if (k == mem) return (char *)h; + if (k <= mem) return (char *)h; h += p; mem = mem0; } diff --git a/src/string/wcsstr.c b/src/string/wcsstr.c index 3e28e28..4caaef3 100644 --- a/src/string/wcsstr.c +++ b/src/string/wcsstr.c @@ -84,7 +84,7 @@ static wchar_t *twoway_wcsstr(const wchar_t *h, const wchar_t *n) } /* Compare left half */ for (k=ms+1; k>mem && n[k-1] == h[k-1]; k--); - if (k == mem) return (wchar_t *)h; + if (k <= mem) return (wchar_t *)h; h += p; mem = mem0; } diff --git a/src/time/__tz.c b/src/time/__tz.c index 9d56a61..6d7173c 100644 --- a/src/time/__tz.c +++ b/src/time/__tz.c @@ -121,7 +121,7 @@ int __munmap(void *, size_t); static void do_tzset() { char buf[NAME_MAX+25], *pathname=buf+24; - const char *try, *s; + const char *try, *s, *p; const unsigned char *map = 0; size_t i; static const char search[] = @@ -147,19 +147,16 @@ static void do_tzset() } if (old_tz) memcpy(old_tz, s, i+1); - if (*s == ':') s++; - /* Non-suid can use an absolute tzfile pathname or a relative * pathame beginning with "."; in secure mode, only the * standard path will be searched. */ - if (*s == '/' || *s == '.') { - if (!libc.secure) map = __map_file(s, &map_size); - } else { - for (i=0; s[i] && s[i]!=','; i++) { - if (s[i]=='/') { - size_t l = strlen(s); - if (l > NAME_MAX || strchr(s, '.')) - break; + if (*s == ':' || ((p=strchr(s, '/')) && !memchr(s, ',', p-s))) { + if (*s == ':') s++; + if (*s == '/' || *s == '.') { + if (!libc.secure) map = __map_file(s, &map_size); + } else { + size_t l = strlen(s); + if (l <= NAME_MAX && !strchr(s, '.')) { memcpy(pathname, s, l+1); pathname[l] = 0; for (try=search; !map && *try; try+=l+1) { @@ -167,9 +164,14 @@ static void do_tzset() memcpy(pathname-l, try, l); map = __map_file(pathname-l, &map_size); } - break; } } + if (!map) s = __gmt; + } + if (map && (map_size < 44 || memcmp(map, "TZif", 4))) { + __munmap((void *)map, map_size); + map = 0; + s = __gmt; } zi = map;