diff options
-rw-r--r-- | arch/i386/atomic.h | 5 | ||||
-rw-r--r-- | arch/x86_64/atomic.h | 5 | ||||
-rw-r--r-- | src/env/__environ.c | 7 | ||||
-rw-r--r-- | src/env/__init_security.c | 26 | ||||
-rw-r--r-- | src/env/__libc_start_main.c | 18 | ||||
-rw-r--r-- | src/internal/libc.h | 6 |
6 files changed, 52 insertions, 15 deletions
diff --git a/arch/i386/atomic.h b/arch/i386/atomic.h index 66059af9..77b0b3b7 100644 --- a/arch/i386/atomic.h +++ b/arch/i386/atomic.h @@ -119,5 +119,10 @@ static inline void a_spin() __asm__ __volatile__( "pause" : : : "memory" ); } +static inline void a_crash() +{ + __asm__ __volatile__( "hlt" : : : "memory" ); +} + #endif diff --git a/arch/x86_64/atomic.h b/arch/x86_64/atomic.h index 3235db16..0d3da6f8 100644 --- a/arch/x86_64/atomic.h +++ b/arch/x86_64/atomic.h @@ -118,5 +118,10 @@ static inline void a_spin() __asm__ __volatile__( "pause" : : : "memory" ); } +static inline void a_crash() +{ + __asm__ __volatile__( "hlt" : : : "memory" ); +} + #endif diff --git a/src/env/__environ.c b/src/env/__environ.c index d7bd5e50..0a2786fd 100644 --- a/src/env/__environ.c +++ b/src/env/__environ.c @@ -1,7 +1,6 @@ #include "libc.h" #undef environ -char **___environ = 0; -weak_alias(___environ, __environ); -weak_alias(___environ, _environ); -weak_alias(___environ, environ); +char **__environ = 0; +weak_alias(__environ, _environ); +weak_alias(__environ, environ); diff --git a/src/env/__init_security.c b/src/env/__init_security.c new file mode 100644 index 00000000..5fd12ecb --- /dev/null +++ b/src/env/__init_security.c @@ -0,0 +1,26 @@ +#include <stddef.h> +#include <elf.h> +#include <poll.h> +#include <fcntl.h> +#include "syscall.h" +#include "libc.h" +#include "atomic.h" + +#define AUX_CNT 24 + +void __init_security(size_t *auxv) +{ + size_t i, aux[AUX_CNT] = { 0 }; + struct pollfd pfd[3] = { {.fd=0}, {.fd=1}, {.fd=2} }; + + for (; auxv[0]; auxv+=2) if (auxv[0]<AUX_CNT) aux[auxv[0]] = auxv[1]; + 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)<0) + a_crash(); + libc.secure = 1; +} diff --git a/src/env/__libc_start_main.c b/src/env/__libc_start_main.c index 70af77b5..f31222b2 100644 --- a/src/env/__libc_start_main.c +++ b/src/env/__libc_start_main.c @@ -1,21 +1,21 @@ #include "libc.h" -/* Any use of __environ/environ will override this symbol. */ -char **__dummy_environ = (void *)-1; -weak_alias(__dummy_environ, ___environ); +void __init_security(size_t *); int __libc_start_main( int (*main)(int, char **, char **), int argc, char **argv, int (*init)(int, char **, char **), void (*fini)(void), void (*ldso_fini)(void)) { - /* Save the environment if it may be used by libc/application */ - char **envp = argv+argc+1; - if (___environ != (void *)-1) ___environ = envp; + char **envp = argv+argc+1, **auxv = envp; - /* Avoid writing 0 and triggering unnecessary COW */ - if (ldso_fini) libc.ldso_fini = ldso_fini; - if (fini) libc.fini = fini; + __environ = envp; + do auxv++; while (*auxv); + libc.auxv = (void *)++auxv; + libc.ldso_fini = ldso_fini; + libc.fini = fini; + + __init_security((void *)auxv); /* Execute constructors (static) linked into the application */ if (init) init(argc, argv, envp); diff --git a/src/internal/libc.h b/src/internal/libc.h index 115cd865..d985902c 100644 --- a/src/internal/libc.h +++ b/src/internal/libc.h @@ -7,13 +7,15 @@ struct __libc { void *main_thread; int threaded; - int canceldisable; + int secure; + size_t *auxv; int (*atexit)(void (*)(void)); void (*fini)(void); void (*ldso_fini)(void); volatile int threads_minus_1; - int ofl_lock; + int canceldisable; FILE *ofl_head; + int ofl_lock; }; |