diff options
author | Robert Morris <[email protected]> | 2019-09-20 09:41:03 -0400 |
---|---|---|
committer | Robert Morris <[email protected]> | 2019-09-20 09:41:03 -0400 |
commit | 402e7b56053312f4e96737ee7cd82395c998f00f (patch) | |
tree | 4abf84fc5c23540a012e615e982648eff7a471eb | |
parent | 57e40a020411924dc89fba9fdd22a048ff4513f0 (diff) | |
download | xv6-labs-402e7b56053312f4e96737ee7cd82395c998f00f.tar.gz xv6-labs-402e7b56053312f4e96737ee7cd82395c998f00f.tar.bz2 xv6-labs-402e7b56053312f4e96737ee7cd82395c998f00f.zip |
fix a potential kernel crash
add a regression test for it
-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"}, |