Parcourir la source

Check return value

isundil il y a 9 ans
Parent
commit
cbe0f6b5b0

+ 1 - 1
CMakeLists.txt

@@ -1,6 +1,6 @@
 cmake_minimum_required(VERSION 2.8)
 
-add_library(sllist STATIC lib/sllist/src/create.c lib/sllist/src/add.c lib/sllist/src/at.c lib/sllist/src/del.c)
+add_library(sllist STATIC lib/sllist/src/create.c lib/sllist/src/add.c lib/sllist/src/at.c lib/sllist/src/del.c lib/sllist/src/find.c)
 add_executable(sandbox src/main.c src/mem.c src/exec.c src/param.c src/sandbox.c src/environment.c src/pathutil.c
 	src/ovr_syscall/ovr_write.c src/ovr_syscall/ovr_open.c src/ovr_syscall/ovr_close.c)
 

+ 7 - 0
lib/sllist/include/sllist.h

@@ -55,4 +55,11 @@ void *sllist_removeat(sl_list *list, unsigned int pos);
 **/
 sl_list *sllist_clear(sl_list *list);
 
+/**
+ * Return index of first item, using compare fnc
+ * Return -1 on failure
+ * TODO
+**/
+int sllist_find(sl_list *list, int(*fnc)(const void *cmp, const void *param), const void *param);
+
 #endif /* SL_LIST_H__ */

+ 18 - 0
lib/sllist/src/find.c

@@ -0,0 +1,18 @@
+#include "sllist.h"
+
+int sllist_find(sl_list *list, int(*cmpfnc)(const void *, const void*), const void *param)
+{
+	struct sl_list_item *i = list->first;
+	const int count = sllist_count(list);
+	int _i, _j = 0;
+
+	while (i && _j < count)
+	{
+		for (_i = 0; _i < SL_LIST_BUFLEN && _j < count; ++_i, ++_j)
+			if (cmpfnc(i->data[_i], param) != 0)
+				return _j;
+		i = i->next;
+	}
+	return -1;
+}
+

+ 0 - 2
src/environment.c

@@ -62,7 +62,6 @@ int init_env(t_param *params)
 {
 	if ((params->cmdpath = check_file(params->cmd[0])) == NULL)
 		return -1;
-	params->filetable = sllist_create();
 	asprintf(&(params->tmppath), "%s/sandbox_%ld:%d", params->tmpdir, time(NULL), getpid());
 	if (mkdir(params->tmppath, 0) == -1)
 	{
@@ -75,7 +74,6 @@ int init_env(t_param *params)
 void release_env(t_param *params)
 {
 	rmdir(params->tmppath);
-	sllist_destroy(params->filetable);
 
 	free(params->tmppath);
 	free(params->cmdpath);

+ 13 - 2
src/ovr_syscall/ovr_open.c

@@ -10,11 +10,22 @@ int ovr_open(struct s_sandboxenv *env)
 	char *pathname = getMem(env, (size_t) env->syscall_args[0], NULL);
 	int flags = (int) env->syscall_args[1];
 	mode_t mode = (mode_t) env->syscall_args[2];
-	int ro = !(flags & O_RDWR || flags & O_WRONLY);
+	int ro = !(flags & (O_RDWR | O_WRONLY | O_CREAT | O_TRUNC));
+	t_fileinfo *fileentry;
 
 	if (*pathname != '/')
 		find_fullpath(&pathname, 1);
-	printf("DO open ! ([%s], [%d], [%d])%s\n", pathname, flags, mode, ro ? "- RO" : "- RW");
+	fileentry = get_fileinfo(env, pathname);
+	if (fileentry == NULL && ro)
+	{
+		printf("DO open %s (unmanaged)\n", pathname);
+		fflush(stdout);
+		free(pathname);
+		return 0;
+	}
+	waitForSyscall(env->child_pid, SANDBOX_SYS_EXIT);
+	read_registers(env);
+	printf("DO open ! ([%s], [%d], [%d])%s = %d\n", pathname, flags, mode, ro ? "- RO" : "- RW", env->syscall_no.syscall_return);
 	fflush(stdout);
 	free(pathname);
 	return 0;

+ 2 - 0
src/ovr_syscall/ovr_write.c

@@ -11,8 +11,10 @@ int ovr_write(struct s_sandboxenv *env)
 	char *buf = getMem(env, (size_t) env->syscall_args[1], NULL);
 	int buflen = (int) env->syscall_args[2];
 
+	/*
 	printf("DO WRITE ! ([%d], [%s], [%d])\n", fd, buf, buflen);
 	fflush(stdout);
+	*/
 	free(buf);
 	//env->registers.orig_rax = -1;
 	return 0;

+ 16 - 0
src/pathutil.c

@@ -1,6 +1,7 @@
 #include "sandbox.h"
 #include <unistd.h>
 #include <stdlib.h>
+#include <string.h>
 #include <stdio.h>
 
 void find_fullpath(char **path, int _free)
@@ -16,3 +17,18 @@ void find_fullpath(char **path, int _free)
 	*path = result;
 }
 
+int fileinfo_compare(const void *a, const void *b)
+{
+	return strcmp(((t_fileinfo *)a)->filename, (char *)b) == 0;
+}
+
+t_fileinfo *get_fileinfo(struct s_sandboxenv *env, const char * filename)
+{
+	int i;
+
+	i = sllist_find(env->filetable, fileinfo_compare, filename);
+	if (i == -1)
+		return NULL;
+	return sllist_at(env->filetable, i);
+}
+

+ 38 - 31
src/sandbox.c

@@ -13,16 +13,6 @@
 
 static inline void get_args(struct s_sandboxenv *env)
 {
-#ifdef __x86_64__
-	REGISTER_TYPE result[] = { env->registers.rdi, env->registers.rsi,
-			env->registers.rdx, env->registers.r10,
-			env->registers.r8, env->registers.r9 };
-#else
-	REGISTER_TYPE result[] = { env->registers.ebx, env->registers.ecx,
-			env->registers.edx, env->registers.esi,
-			env->registers.edi, env->registers.ebp };
-#endif
-	memcpy(env->syscall_args, result, sizeof(REGISTER_TYPE) * 6);
 }
 
 static inline void init_syscalls(struct s_sandboxenv *env)
@@ -33,11 +23,15 @@ static inline void init_syscalls(struct s_sandboxenv *env)
 	env->functions[__NR_close] = ovr_close;
 }
 
-static inline int waitForSyscall(const int pid)
+int waitForSyscall(const int pid, int _status)
 {
 	int status;
+	static int current_status = SANDBOX_SYS_EXIT;
 
+	if (current_status == _status || (_status != SANDBOX_SYS_ENTER && _status != SANDBOX_SYS_EXIT))
+		return 0;
 	ptrace(PTRACE_SYSCALL, pid, NULL, 0);
+	current_status = _status;
 	if (waitpid(pid, &status, 0) == -1)
 		return -1;
 	return 0;
@@ -46,51 +40,64 @@ static inline int waitForSyscall(const int pid)
 int manageSyscall(struct s_sandboxenv *env)
 {
 	t_syscall_fnc ovr_fnc;
-	unsigned int syscall_nr;
-
-#ifdef __x86_64__
-	syscall_nr = (unsigned int) env->registers.orig_rax;
-#else
-	syscall_nr = (unsigned int) env->registers.orig_eax;
-#endif
 
-	if (syscall_nr >= NR_syscalls ||
-			!(ovr_fnc = env->functions[syscall_nr]))
+	if (env->syscall_no.syscall_no >= NR_syscalls ||
+			!(ovr_fnc = env->functions[env->syscall_no.syscall_no]))
 	{
-		/* TODO verbose -v */
+		/* Unrecognized syscall */
 		return 0;
 	}
-	get_args(env);
-	(ovr_fnc)(env);
-	return 1;
+	return (ovr_fnc)(env);
+}
+
+void read_registers(struct s_sandboxenv *env)
+{
+	struct iovec iov = { &(env->registers), sizeof(env->registers) };
+
+	ptrace(PTRACE_GETREGSET, env->child_pid, NT_PRSTATUS, &iov);
+#ifdef __x86_64__
+	env->syscall_no.syscall_no = (unsigned int) env->registers.orig_rax;
+	env->syscall_no.syscall_return = (unsigned int) env->registers.rax;
+	REGISTER_TYPE result[] = { env->registers.rdi, env->registers.rsi,
+			env->registers.rdx, env->registers.r10,
+			env->registers.r8, env->registers.r9 };
+#else
+#error "Register result"
+	env->syscall_no.syscall_no = (unsigned int) env->registers.orig_eax;
+	env->syscall_no.syscall_return = (unsigned int) env->registers.eax;
+	REGISTER_TYPE result[] = { env->registers.ebx, env->registers.ecx,
+			env->registers.edx, env->registers.esi,
+			env->registers.edi, env->registers.ebp };
+#endif
+	memcpy(env->syscall_args, result, sizeof(REGISTER_TYPE) * 6);
 }
 
 void doTrace(int pid, const t_param *params)
 {
 	int status;
 	struct s_sandboxenv sandbox_env;
-	struct iovec iov = { &(sandbox_env.registers), sizeof(sandbox_env.registers) };
 
 	ptrace(PTRACE_ATTACH, pid, 0, 0);
 	kill(pid, SIGTRAP);
 	waitpid(pid, &status, 0);
 	sandbox_env.params = params;
 	sandbox_env.child_pid = pid;
+	sandbox_env.filetable = sllist_create();
 	init_syscalls(&sandbox_env);
 
 	while (1)
 	{
-		if (waitForSyscall(pid))
+		if (waitForSyscall(pid, SANDBOX_SYS_ENTER))
 			break;
-		ptrace(PTRACE_GETREGSET, pid, NT_PRSTATUS, &iov);
+		read_registers(&sandbox_env);
 		if (manageSyscall(&sandbox_env))
 			ptrace(PTRACE_SETREGS, pid, 0, &(sandbox_env.registers));
-		if (waitForSyscall(pid))
+		if (waitForSyscall(pid, SANDBOX_SYS_EXIT))
 			break;
-		iov.iov_len = sizeof(sandbox_env.registers);
-		ptrace(PTRACE_GETREGSET, pid, NT_PRSTATUS, &iov);
-		manageSyscall(&sandbox_env);
 	}
+
+	/* TODO */
+	sllist_destroy(sandbox_env.filetable);
 }
 
 int launch_program(const t_param *params)

+ 14 - 1
src/sandbox.h

@@ -13,15 +13,24 @@
 #  define NR_syscalls 386
 # endif
 
+# define SANDBOX_SYS_ENTER 0
+# define SANDBOX_SYS_EXIT  1
+
 # ifdef __x86_64__
 #  define REGISTER_TYPE unsigned long long int
 # else
 #  define REGISTER_TYPE long int
 # endif
 
+typedef struct fd {
+	int fd;
+	int mod;
+} t_fd;
+
 typedef struct {
 	char *filename;
 	sl_list *fds;
+	int local_fd;
 } t_fileinfo;
 
 typedef struct {
@@ -29,7 +38,6 @@ typedef struct {
 	const char *tmpdir;
 	char *cmdpath;
 	char *tmppath;
-	sl_list *filetable;
 } t_param;
 
 struct s_sandboxenv;
@@ -40,6 +48,8 @@ struct s_sandboxenv {
 	t_syscall_fnc functions[NR_syscalls];
 	int child_pid;
 	struct user_regs_struct registers;
+	struct { unsigned int syscall_no; int syscall_return; } syscall_no; 
+	sl_list *filetable;
 	REGISTER_TYPE syscall_args[6];
 };
 
@@ -51,6 +61,8 @@ t_param *parse_argv(const char **av);
 int launch_program(const t_param *params);
 int manageSyscall(struct s_sandboxenv *env);
 void doTrace(int pid, const t_param *params);
+int waitForSyscall(const int pid, int status);
+void read_registers(struct s_sandboxenv *env);
 
 /* exec.c */
 void doExec(int pid_parent, const t_param *params);
@@ -69,6 +81,7 @@ void release_env(t_param *);
 
 /* pathutil.c */
 void find_fullpath(char **path, int free);
+t_fileinfo *get_fileinfo(struct s_sandboxenv *env, const char *filename);
 
 # include "sandbox_syscall.h"
 

+ 9 - 0
test/sllist/main.c

@@ -11,6 +11,11 @@ static inline int test_create()
 	return 0;
 }
 
+int cmp_int(const void *a, const void *b)
+{
+	return a == b;
+}
+
 static inline int test_add()
 {
 	unsigned long long i;
@@ -36,6 +41,10 @@ static inline int test_add()
 	_assertEqual(sllist_at(a, 0), 0);
 	_assertEqual(sllist_at(a, 1023), 2046);
 	_assertEqual(sllist_at(a, 1024), 0);
+	_assertEqual(sllist_find(a, cmp_int, 0), 0);
+	_assertEqual(sllist_find(a, cmp_int, (void *)2), 1);
+	_assertEqual(sllist_find(a, cmp_int, (void *)2046), 1023);
+	_assertEqual(sllist_find(a, cmp_int, (void *)2048), -1);
 	while (sllist_count(a))
 		sllist_popback(a);
 	for (i=0; i < 1024; ++i)