Implement the memcheck.
This commit is contained in:
parent
113093f919
commit
8cd1daf8dd
16
kern/pmap.c
16
kern/pmap.c
|
@ -6,6 +6,7 @@
|
|||
#include <inc/string.h>
|
||||
#include <inc/assert.h>
|
||||
|
||||
#include <kern/monitor.h>
|
||||
#include <kern/pmap.h>
|
||||
#include <kern/kclock.h>
|
||||
#include <kern/env.h>
|
||||
|
@ -562,6 +563,21 @@ int
|
|||
user_mem_check(struct Env *env, const void *va, size_t len, int perm)
|
||||
{
|
||||
// LAB 3: Your code here.
|
||||
const char* bottom = ROUNDDOWN(va, PGSIZE);
|
||||
size_t aligned_count = ROUNDUP(len, PGSIZE) / PGSIZE;
|
||||
pde_t mask = PTE_P | PTE_U | PTE_W;
|
||||
pde_t perms = mask;
|
||||
|
||||
#define VALID ((perms & (perm | PTE_P)) == (perm | PTE_P))
|
||||
#define DO_CHECK if(!VALID) { user_mem_check_addr = (uintptr_t) bottom; return -E_FAULT; }
|
||||
|
||||
while(aligned_count--) {
|
||||
perms &= env->env_pgdir[PDX(bottom)] & mask;
|
||||
DO_CHECK;
|
||||
perms &= (*pgdir_walk(env->env_pgdir, bottom, 0)) & mask;
|
||||
DO_CHECK;
|
||||
bottom += PGSIZE;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -19,26 +19,7 @@ sys_cputs(const char *s, size_t len)
|
|||
{
|
||||
// Check that the user has permission to read memory [s, s+len).
|
||||
// Destroy the environment if not.
|
||||
const char* bottom = ROUNDDOWN(s, PGSIZE);
|
||||
size_t aligned_count = ROUNDUP(len, PGSIZE) / PGSIZE;
|
||||
while(aligned_count--) {
|
||||
if (!(curenv->env_pgdir[PDX(bottom)] & PTE_P)) {
|
||||
cprintf("[%08x] Tried to print unmapped address\n", curenv->env_id);
|
||||
env_destroy(curenv);
|
||||
return;
|
||||
}
|
||||
|
||||
pde_t pgdir_allowed = curenv->env_pgdir[PDX(bottom)] & PTE_U;
|
||||
pde_t pt_allowed = *pgdir_walk(curenv->env_pgdir, bottom, 0) & PTE_U;
|
||||
if(((curenv->env_tf.tf_cs & 0b11) > 1) && !(pt_allowed & pgdir_allowed)) {
|
||||
cprintf("[%08x] Tried to print forbidden memory\n", curenv->env_id);
|
||||
env_destroy(curenv);
|
||||
return;
|
||||
}
|
||||
|
||||
bottom += PGSIZE;
|
||||
}
|
||||
|
||||
user_mem_assert(curenv, s, len, 0);
|
||||
// Print the string supplied by the user.
|
||||
cprintf("%.*s", len, s);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user