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;  }; | 
