Add Fixes to Memory Leaks, Memory Access Validation, Synchronised Processes and Refactoring #38

Merged
sb3923 merged 12 commits from system-calls into userprog-oom 2024-11-13 19:20:20 +00:00
13 changed files with 160 additions and 43 deletions
Showing only changes of commit eb4f23c290 - Show all commits

View File

@@ -46,6 +46,7 @@ static void syscall_close (int fd);
static struct open_file *fd_get_file (int fd); static struct open_file *fd_get_file (int fd);
static void validate_user_pointer (const void *start, size_t size); static void validate_user_pointer (const void *start, size_t size);
static void validate_user_string (const char *str);
/* A struct defining a syscall_function pointer along with its arity. */ /* A struct defining a syscall_function pointer along with its arity. */
typedef struct typedef struct
@@ -140,7 +141,7 @@ syscall_exit (int status)
static pid_t static pid_t
syscall_exec (const char *cmd_line) syscall_exec (const char *cmd_line)
{ {
validate_user_pointer (cmd_line, 1); validate_user_string (cmd_line);
pid_t pid = process_execute(cmd_line); pid_t pid = process_execute(cmd_line);
@@ -159,9 +160,9 @@ syscall_wait (pid_t pid)
pointer. Acquires the file system lock to prevent synchronisation issues, pointer. Acquires the file system lock to prevent synchronisation issues,
and then uses FILESYS_CREATE to create the file, returning the same status */ and then uses FILESYS_CREATE to create the file, returning the same status */
static bool static bool
syscall_create (const char *file UNUSED, unsigned initial_size UNUSED) syscall_create (const char *file, unsigned initial_size)
{ {
validate_user_pointer (file, 1); validate_user_string (file);
lock_acquire (&filesys_lock); lock_acquire (&filesys_lock);
bool status = filesys_create (file, initial_size); bool status = filesys_create (file, initial_size);
@@ -176,7 +177,7 @@ syscall_create (const char *file UNUSED, unsigned initial_size UNUSED)
static bool static bool
syscall_remove (const char *file) syscall_remove (const char *file)
{ {
validate_user_pointer (file, 1); validate_user_string (file);
lock_acquire (&filesys_lock); lock_acquire (&filesys_lock);
bool status = filesys_remove (file); bool status = filesys_remove (file);
@@ -192,7 +193,7 @@ syscall_remove (const char *file)
static int static int
syscall_open (const char *file) syscall_open (const char *file)
{ {
validate_user_pointer (file, 1); validate_user_string (file);
lock_acquire (&filesys_lock); lock_acquire (&filesys_lock);
struct file *ptr = filesys_open (file); struct file *ptr = filesys_open (file);
@@ -418,3 +419,37 @@ validate_user_pointer (const void *start, size_t size)
if (pagedir_get_page (thread_current ()->pagedir, ptr) == NULL) if (pagedir_get_page (thread_current ()->pagedir, ptr) == NULL)
thread_exit (); thread_exit ();
} }
/* Validates if a string is fully contained within user virtual memory. Kills
the thread (by calling thread_exit) if the memory is invalid. Otherwise,
returns (nothing) normally. */
static void
validate_user_string (const char *str)
{
if (str == NULL || !is_user_vaddr (str))
thread_exit ();
size_t length = 0;
size_t offset = (uintptr_t) str % PGSIZE;
/* We move page by page, checking if the page is mapped to physical memory. */
for (;;)
{
void *page = pg_round_down (str + length);
if (!is_user_vaddr(page) ||
pagedir_get_page (thread_current ()->pagedir, page) == NULL)
thread_exit ();
while (offset < PGSIZE)
{
if (*str == '\0')
return; /* We reached the end of the string without issues. */
str++;
offset++;
}
offset = 0; /* Next page will start at the beginning. */
}
}