#include "common.h" #include "sandbox.h" #include #include #include /* _assertNotNull(a); _assertEqual(sllist_count(a), 0); */ void setArgs(struct s_sandboxenv *env, REGISTER_TYPE sysno, REGISTER_TYPE p1, REGISTER_TYPE p2, REGISTER_TYPE p3) { #ifdef __x86_64__ env->syscall_no.syscall_no = env->registers.orig_rax = sysno; env->syscall_args[0] = env->registers.rdi = p1; env->syscall_args[1] = env->registers.rsi = p2; env->syscall_args[2] = env->registers.rdx = p3; #else env->syscall_no.syscall_no = env->registers.orig_eax = sysno; env->syscall_args[0] = env->registers.ebx = p1; env->syscall_args[1] = env->registers.ecx = p2; env->syscall_args[2] = env->registers.edx = p3; #endif } void setResult(struct s_sandboxenv *env, REGISTER_TYPE result) { env->syscall_no.syscall_return = result; } int fakeread(int fd, char *buf, int buflen, struct s_sandboxenv *env) { setArgs(env, (REGISTER_TYPE) __NR_read, (REGISTER_TYPE) fd, (REGISTER_TYPE) buf, (REGISTER_TYPE) buflen); ovr_read(env); return fd; } int fakelseek(int fd, off_t offset, int whence, struct s_sandboxenv *env) { setArgs(env, (REGISTER_TYPE) __NR_lseek, (REGISTER_TYPE) fd, (REGISTER_TYPE) offset, (REGISTER_TYPE) whence); ovr_lseek(env); return fd; } int fakeopen(const char *path, int flags, int mod, struct s_sandboxenv *env) { int fd; setArgs(env, (REGISTER_TYPE) __NR_open, (REGISTER_TYPE) path, (REGISTER_TYPE) flags, (REGISTER_TYPE) mod); setResult(env, (fd = open(path, flags, mod))); ovr_open(env); return fd; } int fakeclose(int fd, struct s_sandboxenv *env) { setArgs(env, (REGISTER_TYPE) __NR_close, (REGISTER_TYPE) fd, 0, 0); ovr_close(env); return fd; } int fakewrite(int fd, char *buf, int len, struct s_sandboxenv *env) { setArgs(env, (REGISTER_TYPE) __NR_write, (REGISTER_TYPE) fd, (REGISTER_TYPE) buf, (REGISTER_TYPE) len); ovr_write(env); #ifdef __x86_64__ if (env->registers.orig_rax == __NR_write) env->registers.rax = write(fd, buf, len); return env->registers.rax; #else if (env->registers.orig_eax == __NR_write) env->registers.eax = write(fd, buf, len); return env->registers.eax; #endif } int test_open(struct s_sandboxenv *env, int *final_fd) { t_fileinfo *fi; t_fd *fd_struct; close(open("_test", O_CREAT, 0644)); _assertEqual(sllist_count(env->filetable), 0); int fd = fakeopen("_test", O_RDONLY, 0, env); _assertDiff(fd, -1); _assertEqual(env->syscall_no.syscall_return, fd); _assertEqual(sllist_count(env->filetable), 0); close(fd); fd = fakeopen("_test", O_WRONLY, 0646, env); _assertDiff(fd, -1); _assertEqual(env->syscall_no.syscall_return, fd); _assertEqual(sllist_count(env->filetable), 1); fi = (t_fileinfo *)sllist_at(env->filetable, 0); _assertEqual(sllist_count(fi->fds), 1); _assertTrue(fi->local_fd > 0); int fd2 = fakeopen("_test", O_RDONLY, 0, env); _assertTrue(fd2 > 0); _assertEqual(sllist_count(env->filetable), 1); _assertEqual(sllist_count(fi->fds), 2); fakeclose(fd2, env); _assertEqual(sllist_count(fi->fds), 1); fd_struct = sllist_at(fi->fds, 0); _assertNotNull(fd_struct); _assertEqual(fd_struct->fd, fd); _assertEqual(fd_struct->flags, O_WRONLY); _assertEqual(fd_struct->mod, 0646); *final_fd = fd; return 0; } int test_write(struct s_sandboxenv *env, int fd) { struct stat st; char buf[4]; int lfd; _assertEqual(fakewrite(fd, "test", 4, env), 4); _assertEqual(stat("_test", &st), 0); _assertEqual(st.st_size, 0); #warning TODO /* _assertEqual(fakelseek(fd, 0, SEEK_SET, env), 0); _assertEqual(fakeread(fd, buf, 4, env), 4); _assertEqual(strcmp(buf, "test"), 0); */ apply_fs(env); _assertEqual(fakewrite(fd, "test", 4, env), 4); _assertEqual(stat("_test", &st), 0); _assertEqual(st.st_size, 4); lfd = open("_test", O_RDONLY); read(lfd, buf, 4); _assertStrNEqual(buf, "test", 4); return 0; } int main() { int success = 1; struct s_sandboxenv env; int fd; t_param params; tests_init_env(&env, ¶ms); success &= !test_open(&env, &fd); success &= !test_write(&env, fd); fakeclose(fd, &env); tests_release_env(&env, ¶ms); unlink("_test"); exit(success ? EXIT_SUCCESS: EXIT_FAILURE); }