diff options
| -rw-r--r-- | kernel/vm.c | 5 | ||||
| -rw-r--r-- | user/usertests.c | 13 | 
2 files changed, 17 insertions, 1 deletions
| diff --git a/kernel/vm.c b/kernel/vm.c index e0bc728..b2bfe2c 100644 --- a/kernel/vm.c +++ b/kernel/vm.c @@ -99,6 +99,9 @@ walkaddr(pagetable_t pagetable, uint64 va)    pte_t *pte;    uint64 pa; +  if(va >= MAXVA) +    return 0; +    pte = walk(pagetable, va, 0);    if(pte == 0)      return 0; @@ -408,7 +411,7 @@ copyinstr(pagetable_t pagetable, char *dst, uint64 srcva, uint64 max)    int got_null = 0;    while(got_null == 0 && max > 0){ -    va0 = (uint)PGROUNDDOWN(srcva); +    va0 = PGROUNDDOWN(srcva);      pa0 = walkaddr(pagetable, va0);      if(pa0 == 0)        return -1; diff --git a/user/usertests.c b/user/usertests.c index 0042fe7..7da62d1 100644 --- a/user/usertests.c +++ b/user/usertests.c @@ -1908,6 +1908,18 @@ stacktest(char *s)      exit(xstatus);  } +// copyinstr() used to cast the virtual page address to uint, +// which (with certain wild system call arguments) could +// result in a kernel page fault. +void +pgbug(char *s) +{ +  char *argv[1]; +  argv[0] = 0; +  exec((char*)0xeaeb0b5b00002f5e, argv); +  exit(0); +} +  // run each test in its own process. run returns 1 if child's exit()  // indicates success.  int @@ -1945,6 +1957,7 @@ main(int argc, char *argv[])      void (*f)(char *);      char *s;    } tests[] = { +    {pgbug, "pgbug" },      {reparent, "reparent" },      {twochildren, "twochildren"},      {forkfork, "forkfork"}, | 
