Compare commits

..

1 Commits

Author SHA1 Message Date
EDiasAlberto
987a71ec40 Fix rox checking and make filesys_lock global 2024-11-12 16:00:19 +00:00
4 changed files with 29 additions and 101 deletions

View File

@@ -145,14 +145,6 @@ page_fault (struct intr_frame *f)
write = (f->error_code & PF_W) != 0;
user = (f->error_code & PF_U) != 0;
/* Kernel page fault is further handled by the kernel itself. */
if (!user)
{
f->eip = (void *)f->eax;
f->eax = 0xffffffff;
return;
}
/* To implement virtual memory, delete the rest of the function
body, and replace it with code that brings in the page to
which fault_addr refers. */

View File

@@ -8,6 +8,7 @@
#include <string.h>
#include "userprog/gdt.h"
#include "userprog/pagedir.h"
#include "userprog/syscall.h"
#include "userprog/tss.h"
#include "filesys/directory.h"
#include "filesys/file.h"
@@ -81,8 +82,8 @@ process_execute (const char *cmd)
of the process. */
char *file_name = strtok_r (cmd_copy, " ", &data->cmd_saveptr);
/* Validates that the current file to be executed is a valid file */
if (filesys_open (file_name) == NULL)
/* Validates that the current file to be executed is a valid file */
if (filesys_open (file_name) == NULL)
return TID_ERROR;
/* Create a new thread to execute the command, by initializing

View File

@@ -11,12 +11,8 @@
#include "userprog/process.h"
#include "userprog/pagedir.h"
#include <stdio.h>
#include <stdbool.h>
#include <syscall-nr.h>
#define MAX_SYSCALL_ARGS 3
static struct lock filesys_lock;
static unsigned fd_counter = MIN_USER_FD;
struct open_file
@@ -49,11 +45,7 @@ static unsigned syscall_tell (int fd);
static void syscall_close (int fd);
static struct open_file *fd_get_file (int fd);
static void validate_user_pointer (const void *ptr, size_t size,
bool check_write);
static void validate_user_string (const char *str, bool check_write);
static int get_user (const uint8_t *);
static bool put_user (uint8_t *, uint8_t);
static void *validate_user_pointer (const void *ptr, size_t size);
/* A struct defining a syscall_function pointer along with its arity. */
typedef struct
@@ -103,8 +95,8 @@ static void
syscall_handler (struct intr_frame *f)
{
/* First, read the system call number from the stack. */
validate_user_pointer (f->esp, sizeof (uintptr_t), false);
uintptr_t syscall_number = *(int *)f->esp;
validate_user_pointer (f->esp, 1);
unsigned syscall_number = *(int *) f->esp;
/* Ensures the number corresponds to a system call that can be handled. */
if (syscall_number >= LOOKUP_SIZE)
@@ -114,10 +106,10 @@ syscall_handler (struct intr_frame *f)
/* Next, read and copy the arguments from the stack pointer. */
validate_user_pointer (f->esp + sizeof (uintptr_t),
syscall.arity * sizeof (uintptr_t), false);
uintptr_t args[MAX_SYSCALL_ARGS] = { 0 };
for (int i = 0; i < syscall.arity && i < MAX_SYSCALL_ARGS; i++)
args[i] = *(uintptr_t *)(f->esp + sizeof (uintptr_t) * (i + 1));
syscall.arity * sizeof (uintptr_t));
uintptr_t args[3] = {0};
for (int i=0; i < syscall.arity; i++)
args[i] = *(uintptr_t *) (f->esp + sizeof (uintptr_t) * (i + 1));
/* Call the function that handles this system call with the arguments. When
there is a return value it is stored in f->eax. */
@@ -148,11 +140,9 @@ syscall_exit (int status)
static pid_t
syscall_exec (const char *cmd_line)
{
validate_user_string (cmd_line, false);
validate_user_pointer (cmd_line, 1);
lock_acquire (&filesys_lock);
pid_t pid = process_execute(cmd_line);
lock_release (&filesys_lock);
return pid;
}
@@ -171,7 +161,7 @@ syscall_wait (pid_t pid)
static bool
syscall_create (const char *file UNUSED, unsigned initial_size UNUSED)
{
validate_user_string (file, false);
validate_user_pointer (file, 1);
lock_acquire (&filesys_lock);
bool status = filesys_create (file, initial_size);
@@ -186,7 +176,7 @@ syscall_create (const char *file UNUSED, unsigned initial_size UNUSED)
static bool
syscall_remove (const char *file)
{
validate_user_string (file, false);
validate_user_pointer (file, 1);
lock_acquire (&filesys_lock);
bool status = filesys_remove (file);
@@ -202,7 +192,7 @@ syscall_remove (const char *file)
static int
syscall_open (const char *file)
{
validate_user_string (file, false);
validate_user_pointer (file, 1);
lock_acquire (&filesys_lock);
struct file *ptr = filesys_open (file);
@@ -257,7 +247,7 @@ syscall_read (int fd, void *buffer, unsigned size)
if (fd < 0 || fd == STDOUT_FILENO)
return -1;
validate_user_pointer (buffer, size, true);
validate_user_pointer (buffer, size);
if (fd == STDIN_FILENO)
{
@@ -294,7 +284,7 @@ syscall_write (int fd, const void *buffer, unsigned size)
if (fd <= 0)
return 0;
validate_user_pointer (buffer, size, false);
validate_user_pointer (buffer, size);
if (fd == STDOUT_FILENO)
{
@@ -408,75 +398,17 @@ fd_get_file (int fd)
}
/* Validates if a block of memory starting at PTR and of size SIZE bytes is
fully contained within valid user virtual memory. thread_exit () if the
memory is invalid.
If the size is 0, the function does no checks and returns PTR. */
static void
validate_user_pointer (const void *ptr, size_t size, bool check_write)
fully contained within user virtual memory. Kills the thread (by calling
thread_exit) if the memory is invalid. Otherwise, returns the PTR given.
If the size is 0, the function does no checks and returns PTR.*/
static void *
validate_user_pointer (const void *ptr, size_t size)
{
if (size == 0)
return;
/* ptr < ptr + size - 1, so sufficient to check that (ptr + size -1) is a
valid user virtual memory address. */
void *last = ptr + size - 1;
if (!is_user_vaddr (last))
if (size > 0 && (ptr == NULL ||
!is_user_vaddr (ptr) ||
!is_user_vaddr (ptr + size - 1) ||
pagedir_get_page (thread_current()->pagedir, ptr) == NULL))
thread_exit ();
ptr = pg_round_down (ptr);
while (ptr <= last)
{
int result;
/* Check read access to pointer. */
if ((result = get_user (ptr)) == -1)
thread_exit ();
/* Check write access to pointer (if required). */
if (check_write && !put_user (ptr, result))
thread_exit ();
ptr += PGSIZE;
}
}
/* Validates of a C-string starting at ptr is fully contained within valid
user virtual memory. thread_exit () if the memory is invalid. */
static void
validate_user_string (const char *ptr, bool check_write)
{
while (true)
{
if (!is_user_vaddr (ptr))
thread_exit ();
int result;
if ((result = get_user ((const uint8_t *)ptr)) == -1)
thread_exit ();
if (check_write && !put_user ((uint8_t *)ptr, result))
thread_exit ();
if (*ptr == '\0')
return;
ptr++;
}
return (void *) ptr;
}
/* PROVIDED BY SPEC.
Reads a byte at user virtual address UADDR.
UADDR must be below PHYS_BASE.
Returns the byte value if successful, -1 if a segfault occurred. */
static int
get_user (const uint8_t *uaddr)
{
int result;
asm ("movl $1f, %0; movzbl %1, %0; 1:" : "=&a"(result) : "m"(*uaddr));
return result;
}
/* PROVIDED BY SPEC.
Writes BYTE to user address UDST.
UDST must be below PHYS_BASE.
Returns true if successful, false if a segfault occurred. */
static bool
put_user (uint8_t *udst, uint8_t byte)
{
int error_code;
asm ("movl $1f, %0; movb %b2, %1; 1:"
: "=&a"(error_code), "=m"(*udst)
: "q"(byte));
return error_code != -1;
}

View File

@@ -2,11 +2,14 @@
#define USERPROG_SYSCALL_H
#include <hash.h>
#include "threads/synch.h"
#define MIN_USER_FD 2
typedef int pid_t;
struct lock filesys_lock;
void syscall_init (void);
unsigned fd_hash (const struct hash_elem *element, void *aux);