Add validate_user_string helper function to validate that a string is fully conatined within user vm

This commit is contained in:
sBubshait
2024-11-13 17:11:37 +00:00
parent 26de38cdba
commit eb4f23c290

View File

@@ -46,6 +46,7 @@ static void syscall_close (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_string (const char *str);
/* A struct defining a syscall_function pointer along with its arity. */
typedef struct
@@ -140,7 +141,7 @@ syscall_exit (int status)
static pid_t
syscall_exec (const char *cmd_line)
{
validate_user_pointer (cmd_line, 1);
validate_user_string (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,
and then uses FILESYS_CREATE to create the file, returning the same status */
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);
bool status = filesys_create (file, initial_size);
@@ -176,7 +177,7 @@ syscall_create (const char *file UNUSED, unsigned initial_size UNUSED)
static bool
syscall_remove (const char *file)
{
validate_user_pointer (file, 1);
validate_user_string (file);
lock_acquire (&filesys_lock);
bool status = filesys_remove (file);
@@ -192,7 +193,7 @@ syscall_remove (const char *file)
static int
syscall_open (const char *file)
{
validate_user_pointer (file, 1);
validate_user_string (file);
lock_acquire (&filesys_lock);
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)
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. */
}
}