user_mem_check/assert now also check for alignment
authorAndrew Waterman <waterman@cs.berkeley.edu>
Thu, 2 Jun 2011 20:50:36 +0000 (13:50 -0700)
committerKevin Klues <klueska@cs.berkeley.edu>
Thu, 3 Nov 2011 00:36:03 +0000 (17:36 -0700)
kern/include/umem.h
kern/src/syscall.c
kern/src/umem.c

index 416a3c3..9bdb37c 100644 (file)
@@ -15,10 +15,10 @@ static inline bool is_user_rwaddr(void *addr);
 
 /* Can they use the area in the manner of perm? */
 void *user_mem_check(struct proc *p, const void *DANGEROUS va, size_t len,
-                     int perm);
+                     size_t align, int perm);
 /* Kills them if they can't use the area in the manner of perm */
 void *user_mem_assert(struct proc *p, const void *DANGEROUS va, size_t len, 
-                      int perm);
+                      size_t align, int perm);
 
 /* Copy from proc p into the kernel's dest from src */
 int memcpy_from_user(struct proc *p, void *dest, const void *DANGEROUS va,
index 64a1e4e..c1f7d2f 100644 (file)
@@ -731,7 +731,7 @@ static ssize_t sys_serial_read(env_t* e, char *DANGEROUS _buf, size_t len)
                return 0;
 
        #ifdef __CONFIG_SERIAL_IO__
-           char *COUNT(len) buf = user_mem_assert(e, _buf, len, PTE_USER_RO);
+           char *COUNT(len) buf = user_mem_assert(e, _buf, len, 1, PTE_USER_RO);
                size_t bytes_read = 0;
                int c;
                while((c = serial_read_byte()) != -1) {
@@ -751,7 +751,7 @@ static ssize_t sys_serial_write(env_t* e, const char *DANGEROUS buf, size_t len)
        if (len == 0)
                return 0;
        #ifdef __CONFIG_SERIAL_IO__
-               char *COUNT(len) _buf = user_mem_assert(e, buf, len, PTE_USER_RO);
+               char *COUNT(len) _buf = user_mem_assert(e, buf, len, 1, PTE_USER_RO);
                for(int i =0; i<len; i++)
                        serial_send_byte(buf[i]);
                return (ssize_t)len;
@@ -784,7 +784,7 @@ static ssize_t sys_eth_read(env_t* e, char *DANGEROUS buf)
 
                spin_unlock(&packet_buffers_lock);
 
-               char* _buf = user_mem_assert(e, buf, len, PTE_U);
+               char* _buf = user_mem_assert(e, buf, len, 1, PTE_U);
 
                memcpy(_buf, ptr, len);
 
@@ -1419,7 +1419,7 @@ void run_local_syscall(struct syscall *sysc)
        struct per_cpu_info *pcpui = &per_cpu_info[core_id()];
 
        /* TODO: (UMEM) assert / pin the memory for the sysc */
-       user_mem_assert(pcpui->cur_proc, sysc, sizeof(struct syscall), PTE_USER_RW);
+       user_mem_assert(pcpui->cur_proc, sysc, sizeof(struct syscall), sizeof(uintptr_t), PTE_USER_RW);
        pcpui->cur_sysc = sysc;                 /* let the core know which sysc it is */
        sysc->retval = syscall(pcpui->cur_proc, sysc->num, sysc->arg0, sysc->arg1,
                               sysc->arg2, sysc->arg3, sysc->arg4, sysc->arg5);
index 5fa4bac..4728460 100644 (file)
@@ -51,13 +51,12 @@ static void *DANGEROUS RACY user_mem_check_addr;
  * @return NULL trying to access this range of virtual addresses is not allowed
  */
 void *user_mem_check(struct proc *p, const void *DANGEROUS va, size_t len,
-                     int perm)
+                     size_t align, int perm)
 {
-       if (len == 0) {
-               warn("Called user_mem_check with a len of 0. Don't do that. Returning NULL");
+       align--;
+       if(((align+1) & align) || ((uintptr_t)va & align) || (len & align))
                return NULL;
-       }
-       
+
        // TODO - will need to sort this out wrt page faulting / PTE_P
        // also could be issues with sleeping and waking up to find pages
        // are unmapped, though i think the lab ignores this since the 
@@ -115,14 +114,9 @@ void *user_mem_check(struct proc *p, const void *DANGEROUS va, size_t len,
  * GIANT WARNING: this could fuck up your refcnting for p if p was an
  * edible/refcounted reference.  (fix is to return, or just not use this) */
 void *user_mem_assert(struct proc *p, const void *DANGEROUS va, size_t len,
-                       int perm)
+                      size_t align, int perm)
 {
-       if (len == 0) {
-               warn("Called user_mem_assert with a len of 0. Don't do that. Returning NULL");
-               return NULL;
-       }
-       
-       void *COUNT(len) res = user_mem_check(p, va, len, perm | PTE_USER_RO);
+       void* res = user_mem_check(p, va, len, align, perm | PTE_USER_RO);
        if (!res) {
                cprintf("[%08x] user_mem_check assertion failure for "
                        "va %08x\n", p->pid, user_mem_check_addr);