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/string.h>
|
||||||
#include <inc/assert.h>
|
#include <inc/assert.h>
|
||||||
|
|
||||||
|
#include <kern/monitor.h>
|
||||||
#include <kern/pmap.h>
|
#include <kern/pmap.h>
|
||||||
#include <kern/kclock.h>
|
#include <kern/kclock.h>
|
||||||
#include <kern/env.h>
|
#include <kern/env.h>
|
||||||
|
@ -562,6 +563,21 @@ int
|
||||||
user_mem_check(struct Env *env, const void *va, size_t len, int perm)
|
user_mem_check(struct Env *env, const void *va, size_t len, int perm)
|
||||||
{
|
{
|
||||||
// LAB 3: Your code here.
|
// 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;
|
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).
|
// Check that the user has permission to read memory [s, s+len).
|
||||||
// Destroy the environment if not.
|
// Destroy the environment if not.
|
||||||
const char* bottom = ROUNDDOWN(s, PGSIZE);
|
user_mem_assert(curenv, s, len, 0);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Print the string supplied by the user.
|
// Print the string supplied by the user.
|
||||||
cprintf("%.*s", len, s);
|
cprintf("%.*s", len, s);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user