From 7fe92cf8e1497051fbcc05ed2b7893b523beb02f Mon Sep 17 00:00:00 2001 From: Brian Harring Date: Thu, 6 Oct 2005 18:23:46 +0000 Subject: nuking this directory, since it's no longer used. svn path=/main/branches/2.0/; revision=2115 --- src/sandbox-dev/libsandbox.c | 1214 ------------------------------------------ 1 file changed, 1214 deletions(-) delete mode 100644 src/sandbox-dev/libsandbox.c (limited to 'src/sandbox-dev/libsandbox.c') diff --git a/src/sandbox-dev/libsandbox.c b/src/sandbox-dev/libsandbox.c deleted file mode 100644 index 1de50e982..000000000 --- a/src/sandbox-dev/libsandbox.c +++ /dev/null @@ -1,1214 +0,0 @@ -/* - * Path sandbox for the gentoo linux portage package system, initially - * based on the ROCK Linux Wrapper for getting a list of created files - * - * to integrate with bash, bash should have been built like this - * - * ./configure --prefix= --host= --without-gnu-malloc - * - * it's very important that the --enable-static-link option is NOT specified - * - * Copyright (C) 2001 Geert Bevin, Uwyn, http://www.uwyn.com - * Distributed under the terms of the GNU General Public License, v2 or later - * Author : Geert Bevin - * - * Post Bevin leaving Gentoo ranks: - * -------------------------------- - * Ripped out all the wrappers, and implemented those of InstallWatch. - * Losts of cleanups and bugfixes. Implement a execve that forces $LIBSANDBOX - * in $LD_PRELOAD. Reformat the whole thing to look somewhat like the reworked - * sandbox.c from Brad House . - * - * Martin Schlemmer (18 Aug 2002) - * - * Partly Copyright (C) 1998-9 Pancrazio `Ezio' de Mauro , - * as some of the InstallWatch code was used. - * - * - * $Id: /var/cvsroot/gentoo-src/portage/src/sandbox-dev/Attic/libsandbox.c,v 1.4 2002/12/16 22:28:05 jrray Exp $ - * - */ - -/* Uncomment below to enable wrapping of mknod(). - * This is broken currently. */ -/* #define WRAP_MKNOD */ - - -#define open xxx_open -#define open64 xxx_open64 - -/* Wrapping mknod, do not have any effect, and - * wrapping __xmknod causes calls to it to segfault - */ -#ifdef WRAP_MKNOD -# define __xmknod xxx___xmknod -#endif - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#ifdef WRAP_MKNOD -# undef __xmknod -#endif - -#undef open -#undef open64 - -#include "localdecls.h" -#include "sandbox.h" - -#define PIDS_FILE "/tmp/sandboxpids.tmp" - -#define FUNCTION_SANDBOX_SAFE(func, path) \ - ((0 == is_sandbox_on()) || (1 == before_syscall(func, path))) - -#define FUNCTION_SANDBOX_SAFE_INT(func, path, flags) \ - ((0 == is_sandbox_on()) || (1 == before_syscall_open_int(func, path, flags))) - -#define FUNCTION_SANDBOX_SAFE_CHAR(func, path, mode) \ - ((0 == is_sandbox_on()) || (1 == before_syscall_open_char(func, path, mode))) - - -/* Macro to check if a wrapper is defined, if not - * then try to resolve it again. */ -#define check_dlsym(name) \ -{ \ - int old_errno=errno; \ - if (!true_ ## name) true_ ## name=get_dlsym(#name); \ - errno=old_errno; \ -} - -static char sandbox_lib[255]; - -typedef struct { - char *last_env; - int count; - char **strs; -} sbprefix_t; - -typedef struct { - int show_access_violation; - sbprefix_t deny; - sbprefix_t read; - sbprefix_t write; - sbprefix_t predict; -} sbcontext_t; - -/* glibc modified realpath() functions */ -char *erealpath (const char *name, char *resolved); - -static void init_wrappers(void); -static void *get_dlsym(const char *); -static void canonicalize(const char *, char *); -static int check_access(sbcontext_t *, const char *, const char *); -static int check_syscall(sbcontext_t *, const char *, const char *); -static int before_syscall(const char *, const char *); -static int before_syscall_open_int(const char *, const char *, int); -static int before_syscall_open_char(const char *, const char *, const char *); -static void clean_env_entries(sbprefix_t *); -static void init_context(sbcontext_t *); -static void init_env_entries(sbprefix_t *, char *); -static char* filter_path(const char*); -static int is_sandbox_on(); -static int is_sandbox_pid(); - -/* Wrapped functions */ - -extern int chmod(const char *, mode_t); -static int(*true_chmod)(const char *, mode_t); -extern int chown(const char *, uid_t, gid_t); -static int(*true_chown)(const char *, uid_t, gid_t); -extern int creat(const char *, mode_t); -static int(*true_creat)(const char *, mode_t); -extern FILE *fopen(const char *,const char*); -static FILE *(*true_fopen)(const char *,const char*); -extern int lchown(const char *, uid_t, gid_t); -static int(*true_lchown)(const char *, uid_t, gid_t); -extern int link(const char *, const char *); -static int(*true_link)(const char *, const char *); -extern int mkdir(const char *, mode_t); -static int(*true_mkdir)(const char *, mode_t); -extern DIR *opendir(const char *); -static DIR *(*true_opendir)(const char *); -#ifdef WRAP_MKNOD -extern int __xmknod(const char *, mode_t, dev_t); -static int(*true___xmknod)(const char *, mode_t, dev_t); -#endif -extern int open(const char *, int, ...); -static int(*true_open)(const char *, int, ...); -extern int rename(const char *, const char *); -static int(*true_rename)(const char *, const char *); -extern int rmdir(const char *); -static int(*true_rmdir)(const char *); -extern int symlink(const char *, const char *); -static int(*true_symlink)(const char *, const char *); -extern int truncate(const char *, TRUNCATE_T); -static int(*true_truncate)(const char *, TRUNCATE_T); -extern int unlink(const char *); -static int(*true_unlink)(const char *); - -#if (GLIBC_MINOR >= 1) - -extern int creat64(const char *, __mode_t); -static int(*true_creat64)(const char *, __mode_t); -extern FILE *fopen64(const char *,const char *); -static FILE *(*true_fopen64)(const char *,const char *); -extern int open64(const char *, int, ...); -static int(*true_open64)(const char *, int, ...); -extern int truncate64(const char *, __off64_t); -static int(*true_truncate64)(const char *, __off64_t); - -#endif - -extern int execve(const char *filename, char *const argv [], char *const envp[]); -static int (*true_execve)(const char *, char *const [], char *const []); - -static sbcontext_t* sbcontext = NULL; -static sem_t ctxsem; - -/* - * Initialize the shabang - */ - -static void init_wrappers(void) -{ - void *libc_handle = NULL; - -#ifdef BROKEN_RTLD_NEXT -// printf ("RTLD_LAZY"); - libc_handle = dlopen(LIBC_VERSION, RTLD_LAZY); -#else -// printf ("RTLD_NEXT"); - libc_handle = RTLD_NEXT; -#endif - - true_chmod = dlsym(libc_handle, "chmod"); - true_chown = dlsym(libc_handle, "chown"); - true_creat = dlsym(libc_handle, "creat"); - true_fopen = dlsym(libc_handle, "fopen"); - true_lchown = dlsym(libc_handle, "lchown"); - true_link = dlsym(libc_handle, "link"); - true_mkdir = dlsym(libc_handle, "mkdir"); - true_opendir = dlsym(libc_handle, "opendir"); -#ifdef WRAP_MKNOD - true___xmknod = dlsym(libc_handle, "__xmknod"); -#endif - true_open = dlsym(libc_handle, "open"); - true_rename = dlsym(libc_handle, "rename"); - true_rmdir = dlsym(libc_handle, "rmdir"); - true_symlink = dlsym(libc_handle, "symlink"); - true_truncate = dlsym(libc_handle, "truncate"); - true_unlink = dlsym(libc_handle, "unlink"); - -#if (GLIBC_MINOR >= 1) - true_creat64 = dlsym(libc_handle, "creat64"); - true_fopen64 = dlsym(libc_handle, "fopen64"); - true_open64 = dlsym(libc_handle, "open64"); - true_truncate64 = dlsym(libc_handle, "truncate64"); -#endif - - true_execve = dlsym(libc_handle, "execve"); -} - -void _init(void) -{ - int old_errno = errno; - char *tmp_string = NULL; - - if (sem_init(&ctxsem, 0, 1)) { - fprintf(stderr, "Failed to create semaphore\n"); - abort(); - } - - init_wrappers(); - - /* Get the path and name to this library */ - tmp_string = get_sandbox_lib("/"); - strncpy(sandbox_lib, tmp_string, 254); - - if (tmp_string) free(tmp_string); - tmp_string = NULL; - - errno = old_errno; -} - -void _fini(void) -{ - if (sbcontext) { - clean_env_entries(&sbcontext->deny); - clean_env_entries(&sbcontext->read); - clean_env_entries(&sbcontext->write); - clean_env_entries(&sbcontext->predict); - free(sbcontext); - sbcontext = NULL; - } - - /* free the semaphore */ - sem_destroy(&ctxsem); -} - -static void canonicalize(const char *path, char *resolved_path) -{ - int old_errno = errno; - - /* If path == NULL, return or we get a segfault */ - if (NULL == path) return; - - if(!erealpath(path, resolved_path) && (path[0] != '/')) { - /* The path could not be canonicalized, append it - * to the current working directory if it was not - * an absolute path - */ - getcwd(resolved_path, MAXPATHLEN - 2); - strcat(resolved_path, "/"); - strncat(resolved_path, path, MAXPATHLEN - 1 - strlen(resolved_path)); - erealpath(resolved_path, resolved_path); - } - - errno = old_errno; -} - -static void *get_dlsym(const char *symname) -{ - void *libc_handle = NULL; - void *symaddr = NULL; - -#ifdef BROKEN_RTLD_NEXT - libc_handle = dlopen(LIBC_VERSION, RTLD_LAZY); - if (!libc_handle) { - printf("libsandbox.so: Can't dlopen libc: %s\n", dlerror()); - abort(); - } -#else - libc_handle = RTLD_NEXT; -#endif - - symaddr = dlsym(libc_handle, symname); - if (!symaddr) { - printf("libsandbox.so: Can't resolve %s: %s\n", symname, dlerror()); - abort(); - } - - return symaddr; -} - -/* - * Wrapper Functions - */ - -int chmod(const char *path, mode_t mode) -{ - int result = -1; - char canonic[MAXPATHLEN]; - - canonicalize(path, canonic); - - if FUNCTION_SANDBOX_SAFE("chmod", canonic) { - check_dlsym(chmod); - result = true_chmod(path, mode); - } - - return result; -} - -int chown(const char *path, uid_t owner, gid_t group) -{ - int result = -1; - char canonic[MAXPATHLEN]; - - canonicalize(path, canonic); - - if FUNCTION_SANDBOX_SAFE("chown", canonic) { - check_dlsym(chown); - result = true_chown(path, owner, group); - } - - return result; -} - -int creat(const char *pathname, mode_t mode) -{ -/* Is it a system call? */ - int result = -1; - char canonic[MAXPATHLEN]; - - canonicalize(pathname, canonic); - - if FUNCTION_SANDBOX_SAFE("creat", canonic) { - check_dlsym(open); - result = true_open(pathname, O_CREAT | O_WRONLY | O_TRUNC, mode); - } - - return result; -} - -FILE *fopen(const char *pathname, const char *mode) -{ - FILE *result = NULL; - char canonic[MAXPATHLEN]; - - canonicalize(pathname, canonic); - - if FUNCTION_SANDBOX_SAFE_CHAR("fopen", canonic, mode) { - check_dlsym(fopen); - result = true_fopen(pathname,mode); - } - - return result; -} - -int lchown(const char *path, uid_t owner, gid_t group) -{ -/* Linux specific? */ - int result = -1; - char canonic[MAXPATHLEN]; - - canonicalize(path, canonic); - - if FUNCTION_SANDBOX_SAFE("lchown", canonic) { - check_dlsym(chown); - result = true_chown(path, owner, group); - } - - return result; -} - -int link(const char *oldpath, const char *newpath) -{ - int result = -1; - char old_canonic[MAXPATHLEN], new_canonic[MAXPATHLEN]; - - canonicalize(oldpath, old_canonic); - canonicalize(newpath, new_canonic); - - if FUNCTION_SANDBOX_SAFE("link", new_canonic) { - check_dlsym(link); - result = true_link(oldpath, newpath); - } - - return result; -} - -int mkdir(const char *pathname, mode_t mode) -{ - int result = -1; - char canonic[MAXPATHLEN]; - - canonicalize(pathname, canonic); - - if FUNCTION_SANDBOX_SAFE("mkdir", canonic) { - check_dlsym(mkdir); - result = true_mkdir(pathname, mode); - } - - return result; -} - -DIR *opendir(const char *name) -{ - DIR *result = NULL; - char canonic[MAXPATHLEN]; - - canonicalize(name, canonic); - - if FUNCTION_SANDBOX_SAFE("opendir", canonic) { - check_dlsym(opendir); - result = true_opendir(name); - } - - return result; -} - -#ifdef WRAP_MKNOD - -int __xmknod(const char *pathname, mode_t mode, dev_t dev) -{ - int result = -1; - char canonic[MAXPATHLEN]; - - canonicalize(pathname, canonic); - - if FUNCTION_SANDBOX_SAFE("__xmknod", canonic) { - check_dlsym(__xmknod); - result = true___xmknod(pathname, mode, dev); - } - - return result; -} - -#endif - -int open(const char *pathname, int flags, ...) -{ -/* Eventually, there is a third parameter: it's mode_t mode */ - va_list ap; - mode_t mode = 0; - int result = -1; - char canonic[MAXPATHLEN]; - - if (flags & O_CREAT) { - va_start(ap, flags); - mode = va_arg(ap, mode_t); - va_end(ap); - } - - canonicalize(pathname, canonic); - - if FUNCTION_SANDBOX_SAFE_INT("open", canonic, flags) { - /* We need to resolve open() realtime in some cases, - * else we get a segfault when running /bin/ps, etc - * in a sandbox */ - check_dlsym(open); - result=true_open(pathname, flags, mode); - } - - return result; -} - -int rename(const char *oldpath, const char *newpath) -{ - int result = -1; - char old_canonic[MAXPATHLEN], new_canonic[MAXPATHLEN]; - - canonicalize(oldpath, old_canonic); - canonicalize(newpath, new_canonic); - - if FUNCTION_SANDBOX_SAFE("rename", new_canonic) { - check_dlsym(rename); - result = true_rename(oldpath, newpath); - } - - return result; -} - -int rmdir(const char *pathname) -{ - int result = -1; - char canonic[MAXPATHLEN]; - - canonicalize(pathname, canonic); - - if FUNCTION_SANDBOX_SAFE("rmdir", canonic) { - check_dlsym(rmdir); - result = true_rmdir(pathname); - } - - return result; -} - -int symlink(const char *oldpath, const char *newpath) -{ - int result = -1; - char old_canonic[MAXPATHLEN], new_canonic[MAXPATHLEN]; - - canonicalize(oldpath, old_canonic); - canonicalize(newpath, new_canonic); - - if FUNCTION_SANDBOX_SAFE("symlink", new_canonic) { - check_dlsym(symlink); - result = true_symlink(oldpath, newpath); - } - - return result; -} - -int truncate(const char *path, TRUNCATE_T length) -{ - int result = -1; - char canonic[MAXPATHLEN]; - - canonicalize(path, canonic); - - if FUNCTION_SANDBOX_SAFE("truncate", canonic) { - check_dlsym(truncate); - result = true_truncate(path, length); - } - - return result; -} - -int unlink(const char *pathname) -{ - int result = -1; - char canonic[MAXPATHLEN]; - - canonicalize(pathname, canonic); - - if FUNCTION_SANDBOX_SAFE("unlink", canonic) { - check_dlsym(unlink); - result = true_unlink(pathname); - } - - return result; -} - -#if (GLIBC_MINOR >= 1) - -int creat64(const char *pathname, __mode_t mode) -{ -/* Is it a system call? */ - int result = -1; - char canonic[MAXPATHLEN]; - - canonicalize(pathname, canonic); - - if FUNCTION_SANDBOX_SAFE("creat64", canonic) { - check_dlsym(open64); - result = true_open64(pathname, O_CREAT | O_WRONLY | O_TRUNC, mode); - } - - return result; -} - -FILE *fopen64(const char *pathname, const char *mode) -{ - FILE *result = NULL; - char canonic[MAXPATHLEN]; - - canonicalize(pathname, canonic); - - if FUNCTION_SANDBOX_SAFE_CHAR("fopen64", canonic, mode) { - check_dlsym(fopen64); - result = true_fopen(pathname,mode); - } - - return result; -} - -int open64(const char *pathname, int flags, ...) -{ -/* Eventually, there is a third parameter: it's mode_t mode */ - va_list ap; - mode_t mode = 0; - int result = -1; - char canonic[MAXPATHLEN]; - - if (flags & O_CREAT) { - va_start(ap, flags); - mode = va_arg(ap, mode_t); - va_end(ap); - } - - canonicalize(pathname, canonic); - - if FUNCTION_SANDBOX_SAFE_INT("open64", canonic, flags) { - check_dlsym(open64); - result=true_open64(pathname, flags, mode); - } - - return result; -} - -int truncate64(const char *path, __off64_t length) -{ - int result = -1; - char canonic[MAXPATHLEN]; - - canonicalize(path, canonic); - - if FUNCTION_SANDBOX_SAFE("truncate64", canonic) { - check_dlsym(truncate64); - result = true_truncate64(path, length); - } - - return result; -} - -#endif /* GLIBC_MINOR >= 1 */ - -/* - * Exec Wrappers - */ - -int execve(const char *filename, char *const argv [], char *const envp[]) -{ - int old_errno = errno; - int result = -1; - int count = 0; - char canonic[MAXPATHLEN]; - char *old_envp = NULL; - char *new_envp = NULL; - - canonicalize(filename, canonic); - - if FUNCTION_SANDBOX_SAFE("execve", canonic) { - while (envp[count] != NULL) { - if (strstr(envp[count], "LD_PRELOAD=") == envp[count]) { - if (NULL != strstr(envp[count], sandbox_lib)) { - break; - } else { - const int max_envp_len = strlen(envp[count]) + strlen(sandbox_lib) + 1; - - /* Backup envp[count], and set it to our own one which - * contains sandbox_lib */ - old_envp = envp[count]; - new_envp = strndupa(old_envp, max_envp_len - 1); - - /* LD_PRELOAD already have variables other than sandbox_lib, - * thus we have to add sandbox_lib via a white space. */ - if (0 != strcmp(envp[count], "LD_PRELOAD=")) { - strncpy(new_envp + strlen(old_envp), ":", - max_envp_len - strlen(new_envp)); - strncpy(new_envp + strlen(old_envp) + 1, sandbox_lib, - max_envp_len - strlen(new_envp)); - } else { - strncpy(new_envp + strlen(old_envp), sandbox_lib, - max_envp_len - strlen(new_envp)); - } - - /* Valid string? */ - new_envp[max_envp_len] = '\0'; - - /* envp[count] = new_envp; - * - * Get rid of the "read-only" warnings */ - memcpy((void *)&envp[count], &new_envp, sizeof(new_envp)); - - break; - } - } - count++; - } - - errno = old_errno; - check_dlsym(execve); - result = true_execve(filename, argv, envp); - old_errno = errno; - - if (old_envp) { - /* Restore envp[count] again. - * - * envp[count] = old_envp; */ - memcpy((void *)&envp[count], &old_envp, sizeof(old_envp)); - old_envp = NULL; - } - } - - errno = old_errno; - - return result; -} - -/* - * Internal Functions - */ - -#if (GLIBC_MINOR == 1) - -/* This hack is needed for glibc 2.1.1 (and others?) - * (not really needed, but good example) */ -extern int fclose(FILE *); -static int (*true_fclose)(FILE *) = NULL; -int fclose(FILE *file) -{ - int result = - 1; - - check_dlsym(fclose); - result = true_fclose(file); - - return result; -} - -#endif /* GLIBC_MINOR == 1 */ - -static void init_context(sbcontext_t* context) -{ - memset(context, 0, sizeof(sbcontext_t)); - context->show_access_violation = 1; -} - -static int is_sandbox_pid() -{ - int old_errno = errno; - int result = 0; - FILE* pids_stream = NULL; - int pids_file = -1; - int current_pid = 0; - int tmp_pid = 0; - - init_wrappers(); - - pids_stream = true_fopen(PIDS_FILE, "r"); - - if (NULL == pids_stream) { - perror(">>> pids file fopen"); - } - else - { - pids_file = fileno(pids_stream); - - if (pids_file < 0) { - perror(">>> pids file fileno"); - } else { - current_pid = getpid(); - - while (EOF != fscanf(pids_stream, "%d\n", &tmp_pid)) { - if (tmp_pid == current_pid) { - result = 1; - break; - } - } - } - if (EOF == fclose(pids_stream)) { - perror(">>> pids file fclose"); - } - pids_stream = NULL; - pids_file = -1; - } - - errno = old_errno; - - return result; -} - -static void clean_env_entries(sbprefix_t* prefix) -{ - int old_errno = errno; - int i = 0; - - if (NULL != prefix->strs) { - for (i = 0; i < prefix->count; i++) { - if (NULL != prefix->strs[i]) { - free(prefix->strs[i]); - prefix->strs[i] = NULL; - } - } - free(prefix->strs); - prefix->strs = NULL; - prefix->count = 0; - } - if (prefix->last_env) { - free(prefix->last_env); - prefix->last_env = NULL; - } - - errno = old_errno; -} - -static void init_env_entries(sbprefix_t* prefix, char* env) -{ - int old_errno = errno; - char* prefixes_env = getenv(env); - - if (NULL == prefixes_env) { - fprintf(stderr, - "Sandbox error : the %s environmental variable should be defined.\n", - env); - } else { - char *ptr; - int num_colons = 0; - - /* Check to see if the env value has changed since the - last time this was initalized, don't do the work again - if it hasn't. - */ - - if (prefix->last_env && !strcmp(prefix->last_env, prefixes_env)) { - errno = old_errno; - return; - } - - /* Clean any existing entries */ - clean_env_entries(prefix); - - /* Env value is different, update the cached copy */ - prefix->last_env = strdup(prefixes_env); - - ptr = prefixes_env; - while (*ptr) { - if (*ptr++ == ':') ++num_colons; - } - - if (prefix->strs) { - free(prefix->strs); - prefix->strs = 0; - } - prefix->strs = (char**)malloc((num_colons+1) * sizeof(char*)); - if (!prefix->strs) return; - memset(prefix->strs, 0, (num_colons+1) * sizeof(char*)); - prefix->count = 0; - - ptr = prefixes_env; - while (*ptr) { - char *next_colon = strchr(ptr, ':'); - if (next_colon) { - if (next_colon != ptr) { - char *str = strndup(ptr, next_colon-ptr); - if (!str) return; - prefix->strs[prefix->count++] = filter_path(str); - free(str); - } - } else { - prefix->strs[prefix->count++] = filter_path(ptr); - break; - } - - ptr = next_colon+1; - } - } - errno = old_errno; -} - -static char* filter_path(const char* path) -{ - int old_errno = errno; - char* filtered_path = (char *)malloc(MAXPATHLEN * sizeof(char)); - filtered_path[0] = 0; - - canonicalize(path, filtered_path); - - errno = old_errno; - - return filtered_path; -} - -static int check_access(sbcontext_t* sbcontext, const char* func, const char* path) -{ - int old_errno = errno; - int result = -1; - int i = 0; - char* filtered_path = filter_path(path); - - if (!filtered_path) { - errno = old_errno; - return 0; - } - - if ('/' != filtered_path[0]) { - free(filtered_path); - errno = old_errno; - return 0; - } - - if ((0 == strncmp(filtered_path, "/etc/ld.so.preload", 18)) && (is_sandbox_pid())) { - result = 1; - } - - if (-1 == result) { - if (NULL != sbcontext->deny.strs) { - for (i = 0; i < sbcontext->deny.count; i++) { - if (NULL != sbcontext->deny.strs[i]) { - if (0 == strncmp(filtered_path, - sbcontext->deny.strs[i], - strlen(sbcontext->deny.strs[i]))) { - result = 0; - break; - } - } - } - } - - if (-1 == result) { - if ((NULL != sbcontext->read.strs) && - ((0 == strncmp(func, "open_rd", 7)) || - (0 == strncmp(func, "popen", 5)) || - (0 == strncmp(func, "opendir", 7)) || - (0 == strncmp(func, "system", 6)) || - (0 == strncmp(func, "execl", 5)) || - (0 == strncmp(func, "execlp", 6)) || - (0 == strncmp(func, "execle", 6)) || - (0 == strncmp(func, "execv", 5)) || - (0 == strncmp(func, "execvp", 6)) || - (0 == strncmp(func, "execve", 6)) - ) - ) { - for (i = 0; i < sbcontext->read.count; i++) { - if (NULL != sbcontext->read.strs[i]) { - if (0 == strncmp(filtered_path, - sbcontext->read.strs[i], - strlen(sbcontext->read.strs[i]))) { - result = 1; - break; - } - } - } - } - else if ((NULL != sbcontext->write.strs) && - ((0 == strncmp(func, "open_wr", 7)) || - (0 == strncmp(func, "creat", 5)) || - (0 == strncmp(func, "creat64", 7)) || - (0 == strncmp(func, "mkdir", 5)) || - (0 == strncmp(func, "mknod", 5)) || - (0 == strncmp(func, "mkfifo", 6)) || - (0 == strncmp(func, "link", 4)) || - (0 == strncmp(func, "symlink", 7)) || - (0 == strncmp(func, "rename", 6)) || - (0 == strncmp(func, "utime", 5)) || - (0 == strncmp(func, "utimes", 6)) || - (0 == strncmp(func, "unlink", 6)) || - (0 == strncmp(func, "rmdir", 5)) || - (0 == strncmp(func, "chown", 5)) || - (0 == strncmp(func, "lchown", 6)) || - (0 == strncmp(func, "chmod", 5)) || - (0 == strncmp(func, "truncate", 8)) || - (0 == strncmp(func, "ftruncate", 9)) || - (0 == strncmp(func, "truncate64", 10)) || - (0 == strncmp(func, "ftruncate64", 11)) - ) - ) { - struct stat tmp_stat; - -#if 0 // write_denied is never set - - for (i = 0; i < sbcontext->write_denied.count; i++) { - if (NULL != sbcontext->write_denied.strs[i]) { - if (0 == strncmp(filtered_path, - sbcontext->write_denied.strs[i], - strlen(sbcontext->write_denied.strs[i]))) { - result = 0; - break; - } - } - } -#endif - - if (-1 == result) { - for (i = 0; i < sbcontext->write.count; i++) { - if (NULL != sbcontext->write.strs[i]) { - if (0 == strncmp(filtered_path, - sbcontext->write.strs[i], - strlen(sbcontext->write.strs[i]))) { - result = 1; - break; - } - } - } - - if (-1 == result) { - /* hack to prevent mkdir of existing dirs to show errors */ - if (0 == strncmp(func, "mkdir", 5)) { - if (0 == stat(filtered_path, &tmp_stat)) { - sbcontext->show_access_violation = 0; - result = 0; - } - } - - if (-1 == result) { - for (i = 0; i < sbcontext->predict.count; i++) { - if (NULL != sbcontext->predict.strs[i]) { - if (0 == strncmp(filtered_path, - sbcontext->predict.strs[i], - strlen(sbcontext->predict.strs[i]))) { - sbcontext->show_access_violation = 0; - result = 0; - break; - } - } - } - } - } - } - } - } - } - - if (-1 == result) { - result = 0; - } - - if (filtered_path) free(filtered_path); - filtered_path = NULL; - - errno = old_errno; - - return result; -} - -static int check_syscall(sbcontext_t* sbcontext, const char* func, const char* file) -{ - int old_errno = errno; - int result = 1; - struct stat log_stat; - char* log_path = NULL; - char* absolute_path = NULL; - char* tmp_buffer = NULL; - int log_file = 0; - struct stat debug_log_stat; - char* debug_log_env = NULL; - char* debug_log_path = NULL; - int debug_log_file = 0; - char buffer[512]; - - init_wrappers(); - - if ('/' == file[0]) { - absolute_path = (char *)malloc((strlen(file) + 1) * sizeof(char)); - sprintf(absolute_path, "%s", file); - } else { - tmp_buffer = get_current_dir_name(); - absolute_path = (char *)malloc((strlen(tmp_buffer) + 1 + strlen(file) + 1) * sizeof(char)); - sprintf(absolute_path,"%s/%s", tmp_buffer, file); - - if (tmp_buffer) free(tmp_buffer); - tmp_buffer = NULL; - } - - log_path = getenv("SANDBOX_LOG"); - debug_log_env = getenv("SANDBOX_DEBUG"); - debug_log_path = getenv("SANDBOX_DEBUG_LOG"); - - if (((NULL == log_path) || - (0 != strncmp(absolute_path, log_path, strlen(log_path)))) && - ((NULL == debug_log_env) || - (NULL == debug_log_path) || - (0 != strncmp(absolute_path, debug_log_path, strlen(debug_log_path)))) && - (0 == check_access(sbcontext, func, absolute_path)) - ) { - if (1 == sbcontext->show_access_violation) { - fprintf(stderr, "\e[31;01mACCESS DENIED\033[0m %s:%*s%s\n", - func, (int)(10 - strlen(func)), "", absolute_path); - - if (NULL != log_path) { - sprintf(buffer, "%s:%*s%s\n", func, (int)(10 - strlen(func)), "", absolute_path); - - if ((0 == lstat(log_path, &log_stat)) && - (0 == S_ISREG(log_stat.st_mode)) - ) { - fprintf(stderr, - "\e[31;01mSECURITY BREACH\033[0m %s already exists and is not a regular file.\n", - log_path); - } else { - log_file = true_open(log_path, - O_APPEND | O_WRONLY | O_CREAT, - S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); - if(log_file >= 0) { - write(log_file, buffer, strlen(buffer)); - close(log_file); - } - } - } - } - - result = 0; - } - else if (NULL != debug_log_env) { - if (NULL != debug_log_path) { - if (0 != strncmp(absolute_path, debug_log_path, strlen(debug_log_path))) { - sprintf(buffer, "%s:%*s%s\n", func, (int)(10 - strlen(func)), "", absolute_path); - - if ((0 == lstat(debug_log_path, &debug_log_stat)) && - (0 == S_ISREG(debug_log_stat.st_mode)) - ) { - fprintf(stderr, - "\e[31;01mSECURITY BREACH\033[0m %s already exists and is not a regular file.\n", - log_path); - } else { - debug_log_file = true_open(debug_log_path, - O_APPEND | O_WRONLY | O_CREAT, - S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); - if(debug_log_file >= 0) { - write(debug_log_file, buffer, strlen(buffer)); - close(debug_log_file); - } - } - } - } else { - fprintf(stderr, "\e[32;01mACCESS ALLOWED\033[0m %s:%*s%s\n", - func, (int)(10 - strlen(func)), "", absolute_path); - } - } - - if (absolute_path) free(absolute_path); - absolute_path = NULL; - - errno = old_errno; - - return result; -} - -static int is_sandbox_on() -{ - int old_errno = errno; - - /* $SANDBOX_ACTIVE is an env variable that should ONLY - * be used internal by sandbox.c and libsanbox.c. External - * sources should NEVER set it, else the sandbox is enabled - * in some cases when run in parallel with another sandbox, - * but not even in the sandbox shell. - * - * Azarah (3 Aug 2002) - */ - if ((NULL != getenv("SANDBOX_ON")) && - (0 == strncmp(getenv("SANDBOX_ON"), "1", 1)) && - (NULL != getenv("SANDBOX_ACTIVE")) && - (0 == strncmp(getenv("SANDBOX_ACTIVE"), "armedandready", 13)) - ) { - errno = old_errno; - - return 1; - } else { - errno = old_errno; - - return 0; - } -} - -static int before_syscall(const char* func, const char* file) -{ - int old_errno = errno; - int result = 1; - - /* Only allow one thread to access sbcontext at a time */ - sem_wait(&ctxsem); - - if (!sbcontext) { - sbcontext = (sbcontext_t*)malloc(sizeof(sbcontext_t)); - init_context(sbcontext); - } else { - /* sometimes this value gets set to 0 */ - sbcontext->show_access_violation = 1; - } - - init_env_entries(&sbcontext->deny, "SANDBOX_DENY"); - init_env_entries(&sbcontext->read, "SANDBOX_READ"); - init_env_entries(&sbcontext->write, "SANDBOX_WRITE"); - init_env_entries(&sbcontext->predict, "SANDBOX_PREDICT"); - - result = check_syscall(sbcontext, func, file); - - if (sem_post(&ctxsem)) { - fprintf(stderr, "Failed trying to release semaphore\n"); - } - - errno = old_errno; - - if (0 == result) { - errno = EACCES; - } - - return result; -} - -static int before_syscall_open_int(const char* func, const char* file, int flags) -{ - if ((flags & O_WRONLY) || (flags & O_RDWR)) { - return before_syscall("open_wr", file); - } else { - return before_syscall("open_rd", file); - } -} - -static int before_syscall_open_char(const char* func, const char* file, const char* mode) -{ - if ((strcmp(mode, "r") == 0) || (strcmp(mode, "rb") == 0)) { - return before_syscall("open_rd", file); - } else { - return before_syscall("open_wr", file); - } -} - - -// vim:expandtab noai:cindent ai -- cgit v1.2.3-1-g7c22