From d9fc4acc572c6647a4f27b838d35d27d805d190e Mon Sep 17 00:00:00 2001 From: Jason Stubbs Date: Sun, 28 Aug 2005 08:37:44 +0000 Subject: Migration (without history) of the current stable line to subversion. svn path=/main/branches/2.0/; revision=1941 --- src/sandbox/libsandbox.c | 873 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 873 insertions(+) create mode 100644 src/sandbox/libsandbox.c (limited to 'src/sandbox/libsandbox.c') diff --git a/src/sandbox/libsandbox.c b/src/sandbox/libsandbox.c new file mode 100644 index 000000000..d850554c3 --- /dev/null +++ b/src/sandbox/libsandbox.c @@ -0,0 +1,873 @@ +/* +** 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 +** $Header: /var/cvsroot/gentoo-src/portage/src/sandbox/Attic/libsandbox.c,v 1.8 2002/08/05 05:51:39 drobbins Exp $ +*/ + +#define _GNU_SOURCE +#define _REENTRANT + +#define open xxx_open +#define open64 xxx_open64 +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +#undef open +#undef open64 + +#define PIDS_FILE "/tmp/sandboxpids.tmp" + +typedef struct { + int show_access_violation; + char** deny_prefixes; + int num_deny_prefixes; + char** read_prefixes; + int num_read_prefixes; + char** write_prefixes; + int num_write_prefixes; + char** predict_prefixes; + int num_predict_prefixes; + char** write_denied_prefixes; + int num_write_denied_prefixes; +} sbcontext_t; + +int check_access(sbcontext_t*, const char*, const char*); +int check_syscall(sbcontext_t*, const char*, const char*); +int before_syscall(const char*, const char*); +int before_syscall_open_int(const char*, const char*, int); +int before_syscall_open_char(const char*, const char*, const char*); +void clean_env_entries(char***, int*); +char* filter_path(const char*); +void* get_dl_symbol(char*); +void init_context(sbcontext_t*); +void init_env_entries(char***, int*, char*, int); +int is_sandbox_on(); +int is_sandbox_pid(); + +/* Wrapper macros and functions */ + +/* macro definition to wrap functions before and after the + execution of basic file related system-calls. + + nr : the argument number of the system-call's argument that + contains the file name to monitor + rt : the return type of the system call + name : the name of the function call + arg1, arg2, arg3 : the types of the function call's arguments + fl : the argument number of the system-call's argument that + contains the file access flags + md : the argument number of the system-call's argument that + contains the file access mode +*/ +#define wrsysc3(nr, rt, name, arg1, arg2, arg3) \ + \ +/* the function call is defined externally from this file */ \ +extern rt name(arg1, arg2, arg3); \ + \ +/* orig_ ## name is a pointer to a function with three arguments and the + return type of the system call. This will be used to store the pointer + to the system call function and call it. */ \ +rt (*orig_ ## name)(arg1, arg2, arg3) = NULL; \ + \ +rt name(arg1 a1, arg2 a2, arg3 a3) \ +{ \ + rt result = -1; \ + int old_errno = errno; \ + if (0 == is_sandbox_on() || 1 == before_syscall(#name, a ## nr)) \ + { \ + if (!orig_ ## name) \ + { \ + orig_ ## name = get_dl_symbol(#name); \ + } \ + errno = old_errno; \ + result = orig_ ## name(a1, a2, a3); \ + } \ + return result; \ +} + +#define wrsysc2(nr, rt, name, arg1, arg2) \ +extern rt name(arg1, arg2); \ +rt (*orig_ ## name)(arg1, arg2) = NULL; \ + \ +rt name(arg1 a1, arg2 a2) \ +{ \ + rt result = -1; \ + int old_errno = errno; \ + if (0 == is_sandbox_on() || 1 == before_syscall(#name, a ## nr)) \ + { \ + if (!orig_ ## name) \ + { \ + orig_ ## name = get_dl_symbol(#name); \ + } \ + errno = old_errno; \ + result = orig_ ## name(a1, a2); \ + } \ + return result; \ +} + +#define wrsysc1(nr, rt, name, arg1) \ +extern rt name(arg1); \ +rt (*orig_ ## name)(arg1) = NULL; \ + \ +rt name(arg1 a1) \ +{ \ + rt result = -1; \ + int old_errno = errno; \ + if (0 == is_sandbox_on() || 1 == before_syscall(#name, a ## nr)) \ + { \ + if (!orig_ ## name) \ + { \ + orig_ ## name = get_dl_symbol(#name); \ + } \ + errno = old_errno; \ + result = orig_ ## name(a1); \ + } \ + return result; \ +} + +#define wrsysc1ptr(nr, rt, name, arg1) \ +extern rt name(arg1); \ +rt (*orig_ ## name)(arg1) = NULL; \ + \ +rt name(arg1 a1) \ +{ \ + rt result = NULL; \ + int old_errno = errno; \ + if (0 == is_sandbox_on() || 1 == before_syscall(#name, a ## nr)) \ + { \ + if (!orig_ ## name) \ + { \ + orig_ ## name = get_dl_symbol(#name); \ + } \ + errno = old_errno; \ + result = orig_ ## name(a1); \ + } \ + return result; \ +} + +#define wropenint3(nr, fl, rt, name, arg1, arg2, arg3) \ +extern rt name(arg1, arg2, arg3); \ +rt (*orig_ ## name)(arg1, arg2, arg3) = NULL; \ + \ +rt name(arg1 a1, arg2 a2, arg3 a3) \ +{ \ + rt result = -1; \ + int old_errno = errno; \ + if (0 == is_sandbox_on() || \ + 1 == before_syscall_open_int(#name, a ## nr, a ## fl)) \ + { \ + if (!orig_ ## name) \ + { \ + orig_ ## name = get_dl_symbol(#name); \ + } \ + errno = old_errno; \ + result = orig_ ## name(a1, a2, a3); \ + } \ + return result; \ +} + +#define wropenchar2(nr, md, rt, name, arg1, arg2) \ +extern rt name(arg1, arg2); \ +rt (*orig_ ## name)(arg1, arg2) = NULL; \ + \ +rt name(arg1 a1, arg2 a2) \ +{ \ + rt result = NULL; \ + int old_errno = errno; \ + if (0 == is_sandbox_on() || \ + 1 == before_syscall_open_char(#name, a ## nr, a ## md)) \ + { \ + if (!orig_ ## name) \ + { \ + orig_ ## name = get_dl_symbol(#name); \ + } \ + errno = old_errno; \ + result = orig_ ## name(a1, a2); \ + } \ + return result; \ +} + +#define wropenchar3(nr, md, rt, name, arg1, arg2, arg3) \ +extern rt name(arg1, arg2, arg3); \ +rt (*orig_ ## name)(arg1, arg2, arg3) = NULL; \ + \ +rt name(arg1 a1, arg2 a2, arg3 a3) \ +{ \ + rt result = NULL; \ + int old_errno = errno; \ + if (0 == is_sandbox_on() || \ + 1 == before_syscall_open_char(#name, a ## nr, a ## md)) \ + { \ + if (!orig_ ## name) \ + { \ + orig_ ## name = get_dl_symbol(#name); \ + } \ + errno = old_errno; \ + result = orig_ ## name(a1, a2, a3); \ + } \ + return result; \ +} + +#define wrexec3(nr, rt, name, arg1, arg2, arg3) \ +extern rt name(arg1, arg2, arg3); \ +rt (*orig_ ## name)(arg1, arg2, arg3) = NULL; \ + \ +rt name(arg1 a1, arg2 a2, arg3 a3) \ +{ \ + rt result = -1; \ + int old_errno = errno; \ + if (0 == is_sandbox_on() || 1 == before_syscall(#name, a ## nr)) \ + { \ + if (!orig_ ## name) \ + { \ + orig_ ## name = get_dl_symbol(#name); \ + } \ + errno = old_errno; \ + result = orig_ ## name(a1, a2, a3); \ + } \ + return result; \ +} + +#define wrexec2(nr, rt, name, arg1, arg2) \ +extern rt name(arg1, arg2); \ +rt (*orig_ ## name)(arg1, arg2) = NULL; \ + \ +rt name(arg1 a1, arg2 a2) \ +{ \ + rt result = -1; \ + int old_errno = errno; \ + if (0 == is_sandbox_on() || 1 == before_syscall(#name, a ## nr)) \ + { \ + if (!orig_ ## name) \ + { \ + orig_ ## name = get_dl_symbol(#name); \ + } \ + errno = old_errno; \ + result = orig_ ## name(a1, a2); \ + } \ + return result; \ +} + +#define wrexec2va(nr, rt, name, arg1, arg2) \ +extern rt name(arg1, arg2, ...); \ +rt (*orig_ ## name)(arg1, arg2, ...) = NULL; \ + \ +rt name(arg1 a1, arg2 a2, ...) \ +{ \ + void* result = NULL; \ + int old_errno = errno; \ + if (0 == is_sandbox_on() || 1 == before_syscall(#name, a ## nr)) \ + { \ + if (!orig_ ## name) \ + { \ + orig_ ## name = get_dl_symbol(#name); \ + } \ + errno = old_errno; \ + result = __builtin_apply( (void(*)()) orig_ ## name, \ + __builtin_apply_args(), 32 ); \ + old_errno = errno; \ + } \ + if (NULL == result) \ + { \ + return -1; \ + } \ + else \ + { \ + __builtin_return(result); \ + } \ +} + +wropenint3(1, 2, int, open, const char*, int, mode_t) +wropenint3(1, 2, int, open64, const char*, int, mode_t) + +wropenchar2(1, 2, FILE*, fopen, const char*, const char*) +wropenchar2(1, 2, FILE*, fopen64, const char*, const char*) +wropenchar3(1, 2, FILE*, freopen, const char*, const char*, FILE*) + +wropenchar2(1, 2, FILE*, popen, const char*, const char*) + +// write syscalls + +wrsysc2(1, int, creat, const char*, mode_t) +wrsysc2(1, int, creat64, const char*, mode_t) + +wrsysc2(1, int, mkdir, const char*, mode_t) +wrsysc3(1, int, mknod, const char*, mode_t, dev_t) +wrsysc2(1, int, mkfifo, const char*, mode_t) + +wrsysc2(2, int, link, const char*, const char*) +wrsysc2(2, int, symlink, const char*, const char*) +wrsysc2(2, int, rename, const char*, const char*) + +wrsysc2(1, int, utime, const char*, const struct utimbuf*) +wrsysc2(1, int, utimes, const char*, struct timeval*) + +wrsysc1(1, int, unlink, const char*) +wrsysc1(1, int, rmdir, const char*) + +wrsysc3(1, int, chown, const char*, uid_t, gid_t) +wrsysc3(1, int, lchown, const char*, uid_t, gid_t) + +wrsysc2(1, int, chmod, const char*, mode_t) + +/* read syscalls */ + +wrsysc1ptr(1, DIR*, opendir, const char*) + +/* execution syscalls */ +wrsysc1(1, int, system, const char*) + +wrexec2va(1, int, execl, const char*, const char*) +wrexec2va(1, int, execle, const char*, const char*) +wrexec2(1, int, execv, const char*, char* const*) +wrexec3(1, int, execve, const char*, char* const*, char* const*) +/* execlp is redirected to execvp */ +/* execvp is special since it should search the PATH var entries */ +extern int execvp(const char*, char* const*); +int(*orig_execvp)(const char*, char* const*) = NULL; +int execvp(const char* file, char* const* argv) +{ + int result = -1; + int old_errno = errno; + int i = 0; + int allowed = 1; + char** path_entries = NULL; + int num_path_entries = 0; + char constructed_path[255]; + + if (1 == is_sandbox_on()) + { + init_env_entries(&path_entries, &num_path_entries, "PATH", 0); + for (i = 0; i < num_path_entries; i++) + { + strcpy(constructed_path, path_entries[i]); + strcat(constructed_path, "/"); + strcat(constructed_path, file); + if (0 == before_syscall("execvp", constructed_path)) + { + allowed = 0; + break; + } + } + clean_env_entries(&path_entries, &num_path_entries); + } + + if (1 == allowed) + { + if (!orig_execvp) + { + orig_execvp = get_dl_symbol("execvp"); + } + errno = old_errno; + result = orig_execvp(file, argv); + old_errno = errno; + } + errno = old_errno; + return result; +} + +/* lseek, lseek64, fdopen, fchown, fchmod, fcntl, lockf + are not wrapped since they can't be used if open is wrapped correctly + and unaccessible file descriptors are not possible to create */ + +void* get_dl_symbol(char* symname) +{ + void* result = dlsym(RTLD_NEXT, symname); + if (0 == result) + { + fprintf(stderr, "Sandbox : can't resolve %s: %s.\n", symname, dlerror()); + abort(); + } + return result; +} + +void init_context(sbcontext_t* context) +{ + context->show_access_violation = 1; + context->deny_prefixes = NULL; + context->num_deny_prefixes = 0; + context->read_prefixes = NULL; + context->num_read_prefixes = 0; + context->write_prefixes = NULL; + context->num_write_prefixes = 0; + context->predict_prefixes = NULL; + context->num_predict_prefixes = 0; + context->write_denied_prefixes = NULL; + context->num_write_denied_prefixes = 0; +} + +int is_sandbox_pid() +{ + int result = 0; + FILE* pids_stream = NULL; + int pids_file = -1; + int current_pid = 0; + int tmp_pid = 0; + + pids_stream = 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; + } + + return result; +} + +void clean_env_entries(char*** prefixes_array, int* prefixes_num) +{ + int i = 0; + if (NULL != *prefixes_array) + { + for (i = 0; i < *prefixes_num; i++) + { + if (NULL != (*prefixes_array)[i]) + { + free((*prefixes_array)[i]); + (*prefixes_array)[i] = NULL; + } + } + free(*prefixes_array); + *prefixes_array = NULL; + + *prefixes_num = 0; + } +} + +void init_env_entries(char*** prefixes_array, int* prefixes_num, char* env, int warn) +{ + char* prefixes_env = getenv(env); + + if (NULL == prefixes_env) + { + fprintf(stderr, "Sandbox error : the %s environmental variable should be defined.\n", env); + } + else + { + char* buffer = NULL; + int prefixes_env_length = strlen(prefixes_env); + int i = 0; + int num_delimiters = 0; + char* token = NULL; + char* prefix = NULL; + + for (i = 0; i < prefixes_env_length; i++) + { + if (':' == prefixes_env[i]) + { + num_delimiters++; + } + } + + if (num_delimiters > 0) + { + buffer = (char*)malloc(sizeof(char)*(prefixes_env_length+1)); + *prefixes_array = (char**)malloc(sizeof(char*)*(num_delimiters+1)); + + strcpy(buffer, prefixes_env); + token = strtok(buffer, ":"); + while (NULL != token && + strlen(token) > 0) + { + prefix = (char*)malloc(sizeof(char)*(strlen(token)+1)); + strcpy(prefix, token); + (*prefixes_array)[(*prefixes_num)++] = filter_path(prefix); + free(prefix); + token = strtok(NULL, ":"); + } + free(buffer); + buffer = NULL; + } + else if(prefixes_env_length > 0) + { + (*prefixes_array) = (char**)malloc(sizeof(char*)); + + prefix = (char*)malloc(sizeof(char)*(prefixes_env_length+1)); + strcpy(prefix, prefixes_env); + (*prefixes_array)[(*prefixes_num)++] = filter_path(prefix); + free(prefix); + } + } +} + +char* filter_path(const char* path) +{ + int initial_path_length = strlen(path); + char* filtered_path = (char*)malloc(sizeof(char)*(initial_path_length+1)); + int i = 0; + int j = 0; + + for (i = 0, j = 0; i < initial_path_length;) + { + filtered_path[j] = path[i]; + if ('/' == filtered_path[j]) + { + while ('/' == path[i] && + i < initial_path_length) + { + i++; + } + } + else + { + i++; + } + j++; + } + filtered_path[j] = 0; + + return filtered_path; +} + +int check_access(sbcontext_t* sbcontext, const char* func, const char* path) +{ + int result = -1; + int i = 0; + char* filtered_path = filter_path(path); + + if ('/' != path[0]) + { + return 0; + } + + if (0 == strcmp(filtered_path, "/etc/ld.so.preload") && + is_sandbox_pid()) + { + result = 1; + } + + if (-1 == result) + { + if (NULL != sbcontext->deny_prefixes) + { + for (i = 0; i < sbcontext->num_deny_prefixes; i++) + { + if (0 == strncmp(filtered_path, sbcontext->deny_prefixes[i], strlen(sbcontext->deny_prefixes[i]))) + { + result = 0; + break; + } + } + } + + if (-1 == result) + { + if (NULL != sbcontext->read_prefixes && + (0 == strcmp(func, "open_rd") || + 0 == strcmp(func, "popen") || + 0 == strcmp(func, "opendir") || + 0 == strcmp(func, "system") || + 0 == strcmp(func, "execl") || + 0 == strcmp(func, "execlp") || + 0 == strcmp(func, "execle") || + 0 == strcmp(func, "execv") || + 0 == strcmp(func, "execvp") || + 0 == strcmp(func, "execve"))) + { + for (i = 0; i < sbcontext->num_read_prefixes; i++) + { + if (0 == strncmp(filtered_path, sbcontext->read_prefixes[i], strlen(sbcontext->read_prefixes[i]))) + { + result = 1; + break; + } + } + } + else if (NULL != sbcontext->write_prefixes && + (0 == strcmp(func, "open_wr") || + 0 == strcmp(func, "creat") || + 0 == strcmp(func, "creat64") || + 0 == strcmp(func, "mkdir") || + 0 == strcmp(func, "mknod") || + 0 == strcmp(func, "mkfifo") || + 0 == strcmp(func, "link") || + 0 == strcmp(func, "symlink") || + 0 == strcmp(func, "rename") || + 0 == strcmp(func, "utime") || + 0 == strcmp(func, "utimes") || + 0 == strcmp(func, "unlink") || + 0 == strcmp(func, "rmdir") || + 0 == strcmp(func, "chown") || + 0 == strcmp(func, "lchown") || + 0 == strcmp(func, "chmod"))) + { + struct stat tmp_stat; + + for (i = 0; i < sbcontext->num_write_denied_prefixes; i++) + { + if (0 == strncmp(filtered_path, sbcontext->write_denied_prefixes[i], strlen(sbcontext->write_denied_prefixes[i]))) + { + result = 0; + break; + } + } + if (-1 == result) + { + for (i = 0; i < sbcontext->num_write_prefixes; i++) + { + if (0 == strncmp(filtered_path, sbcontext->write_prefixes[i], strlen(sbcontext->write_prefixes[i]))) + { + result = 1; + break; + } + } + + if (-1 == result) + { + /* hack to prevent mkdir of existing dirs to show errors */ + if (strcmp(func, "mkdir") == 0) + { + if (0 == stat(filtered_path, &tmp_stat)) + { + sbcontext->show_access_violation = 0; + result = 0; + } + } + + if (-1 == result) + { + for (i = 0; i < sbcontext->num_predict_prefixes; i++) + { + if (0 == strncmp(filtered_path, sbcontext->predict_prefixes[i], strlen(sbcontext->predict_prefixes[i]))) + { + sbcontext->show_access_violation = 0; + result = 0; + break; + } + } + } + } + } + } + } + } + + if (-1 == result) + { + result = 0; + } + + free(filtered_path); + + return result; +} + +int check_syscall(sbcontext_t* sbcontext, const char* func, const char* file) +{ + int result = 1; + char* absolute_path = NULL; + char* tmp_buffer = NULL; + struct stat log_stat; + char* log_path = 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]; + + if ('/' == file[0]) + { + absolute_path = (char*)malloc(sizeof(char)*(strlen(file)+1)); + sprintf(absolute_path, "%s", file); + } + else + { + tmp_buffer = get_current_dir_name(); + absolute_path = (char*)malloc(sizeof(char)*(strlen(tmp_buffer)+1+strlen(file)+1)); + sprintf(absolute_path,"%s/%s", tmp_buffer, file); + 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 != strcmp(absolute_path, log_path)) && + (NULL == debug_log_env || NULL == debug_log_path || 0 != strcmp(absolute_path, 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 = 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 != strcmp(absolute_path, 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 = 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); + } + } + + free(absolute_path); + absolute_path = NULL; + + return result; +} + +int is_sandbox_on() +{ + /* $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 == strcmp(getenv("SANDBOX_ON"), "1") && + NULL != getenv("SANDBOX_ACTIVE") && + 0 == strcmp(getenv("SANDBOX_ACTIVE"), "armedandready")) + { + return 1; + } + else + { + return 0; + } +} + +int before_syscall(const char* func, const char* file) +{ + int result = 1; + + sbcontext_t sbcontext; + + init_context(&sbcontext); + + init_env_entries(&(sbcontext.deny_prefixes), &(sbcontext.num_deny_prefixes), "SANDBOX_DENY", 1); + init_env_entries(&(sbcontext.read_prefixes), &(sbcontext.num_read_prefixes), "SANDBOX_READ", 1); + init_env_entries(&(sbcontext.write_prefixes), &(sbcontext.num_write_prefixes), "SANDBOX_WRITE", 1); + init_env_entries(&(sbcontext.predict_prefixes), &(sbcontext.num_predict_prefixes), "SANDBOX_PREDICT", 1); + + result = check_syscall(&sbcontext, func, file); + + clean_env_entries(&(sbcontext.deny_prefixes), &(sbcontext.num_deny_prefixes)); + clean_env_entries(&(sbcontext.read_prefixes), &(sbcontext.num_read_prefixes)); + clean_env_entries(&(sbcontext.write_prefixes), &(sbcontext.num_write_prefixes)); + clean_env_entries(&(sbcontext.predict_prefixes), &(sbcontext.num_predict_prefixes)); + + if (0 == result) + { + errno = EACCES; + } + + return result; +} + +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); + } +} + +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); + } +} -- cgit v1.2.3-1-g7c22