From 16c7d34d02045bc7e6165a13c549a7968e074d4b Mon Sep 17 00:00:00 2001 From: John Ousterhout Date: Fri, 14 Dec 2012 14:51:09 -0800 Subject: [PATCH] Added more userprog tests, mostly relating to boundary conditions involving invalid pages (e.g., position system call opcode with first bytes in a valid page and remaining bytes in a nonexistent page). --- src/tests/Make.tests | 1 + src/tests/userprog/Make.tests | 38 ++++++++++++++++++----------- src/tests/userprog/boundary.c | 11 +++++++++ src/tests/userprog/boundary.h | 1 + src/tests/userprog/exec-bound-2.c | 20 +++++++++++++++ src/tests/userprog/exec-bound-2.ck | 9 +++++++ src/tests/userprog/exec-bound-3.c | 18 ++++++++++++++ src/tests/userprog/exec-bound-3.ck | 9 +++++++ src/tests/userprog/exec-bound.c | 12 +++++++++ src/tests/userprog/exec-bound.ck | 18 ++++++++++++++ src/tests/userprog/sc-boundary-3.c | 20 +++++++++++++++ src/tests/userprog/sc-boundary-3.ck | 9 +++++++ 12 files changed, 152 insertions(+), 14 deletions(-) create mode 100644 src/tests/userprog/exec-bound-2.c create mode 100644 src/tests/userprog/exec-bound-2.ck create mode 100644 src/tests/userprog/exec-bound-3.c create mode 100644 src/tests/userprog/exec-bound-3.ck create mode 100644 src/tests/userprog/exec-bound.c create mode 100644 src/tests/userprog/exec-bound.ck create mode 100644 src/tests/userprog/sc-boundary-3.c create mode 100644 src/tests/userprog/sc-boundary-3.ck diff --git a/src/tests/Make.tests b/src/tests/Make.tests index 358e697..32494ca 100644 --- a/src/tests/Make.tests +++ b/src/tests/Make.tests @@ -47,6 +47,7 @@ outputs:: $(OUTPUTS) $(foreach prog,$(PROGS),$(eval $(prog).output: $(prog))) $(foreach test,$(TESTS),$(eval $(test).output: $($(test)_PUTFILES))) $(foreach test,$(TESTS),$(eval $(test).output: TEST = $(test))) +$(foreach test,$(TESTS),$(eval $(test).result: $(test).output $(test).ck)) # Prevent an environment variable VERBOSE from surprising us. VERBOSE = diff --git a/src/tests/userprog/Make.tests b/src/tests/userprog/Make.tests index caadd90..a60b1f0 100644 --- a/src/tests/userprog/Make.tests +++ b/src/tests/userprog/Make.tests @@ -3,19 +3,20 @@ tests/%.output: FILESYSSOURCE = --filesys-size=2 tests/%.output: PUTFILES = $(filter-out kernel.bin loader.bin, $^) -tests/userprog_TESTS = $(addprefix tests/userprog/,args-none \ -args-single args-multiple args-many args-dbl-space sc-bad-sp \ -sc-bad-arg sc-boundary sc-boundary-2 halt exit create-normal \ -create-empty create-null create-bad-ptr create-long create-exists \ -create-bound open-normal open-missing open-boundary open-empty \ -open-null open-bad-ptr open-twice close-normal close-twice close-stdin \ -close-stdout close-bad-fd read-normal read-bad-ptr read-boundary \ -read-zero read-stdout read-bad-fd write-normal write-bad-ptr \ -write-boundary write-zero write-stdin write-bad-fd exec-once exec-arg \ -exec-multiple exec-missing exec-bad-ptr wait-simple wait-twice \ -wait-killed wait-bad-pid multi-recurse multi-child-fd rox-simple \ -rox-child rox-multichild bad-read bad-write bad-read2 bad-write2 \ -bad-jump bad-jump2) +tests/userprog_TESTS = $(addprefix tests/userprog/,args-none \ +args-single args-multiple args-many args-dbl-space sc-bad-sp \ +sc-bad-arg sc-boundary sc-boundary-2 sc-boundary-3 halt exit \ +create-normal create-empty create-null create-bad-ptr create-long \ +create-exists create-bound open-normal open-missing open-boundary \ +open-empty open-null open-bad-ptr open-twice close-normal \ +close-twice close-stdin close-stdout close-bad-fd read-normal \ +read-bad-ptr read-boundary read-zero read-stdout read-bad-fd \ +write-normal write-bad-ptr write-boundary write-zero write-stdin \ +write-bad-fd exec-once exec-arg exec-bound exec-bound-2 \ +exec-bound-3 exec-multiple exec-missing exec-bad-ptr wait-simple \ +wait-twice wait-killed wait-bad-pid multi-recurse multi-child-fd \ +rox-simple rox-child rox-multichild bad-read bad-write bad-read2 \ +bad-write2 bad-jump bad-jump2) tests/userprog_PROGS = $(tests/userprog_TESTS) $(addprefix \ tests/userprog/,child-simple child-args child-bad child-close child-rox) @@ -33,10 +34,12 @@ tests/userprog/bad-jump_SRC = tests/userprog/bad-jump.c tests/main.c tests/userprog/bad-read2_SRC = tests/userprog/bad-read2.c tests/main.c tests/userprog/bad-write2_SRC = tests/userprog/bad-write2.c tests/main.c tests/userprog/bad-jump2_SRC = tests/userprog/bad-jump2.c tests/main.c -tests/userprog/sc-boundary_SRC = tests/userprog/sc-boundary.c \ +tests/userprog/sc-boundary_SRC = tests/userprog/sc-boundary.c \ tests/userprog/boundary.c tests/main.c tests/userprog/sc-boundary-2_SRC = tests/userprog/sc-boundary-2.c \ tests/userprog/boundary.c tests/main.c +tests/userprog/sc-boundary-3_SRC = tests/userprog/sc-boundary-3.c \ +tests/userprog/boundary.c tests/main.c tests/userprog/halt_SRC = tests/userprog/halt.c tests/main.c tests/userprog/exit_SRC = tests/userprog/exit.c tests/main.c tests/userprog/create-normal_SRC = tests/userprog/create-normal.c tests/main.c @@ -77,6 +80,12 @@ tests/userprog/write-stdin_SRC = tests/userprog/write-stdin.c tests/main.c tests/userprog/write-bad-fd_SRC = tests/userprog/write-bad-fd.c tests/main.c tests/userprog/exec-once_SRC = tests/userprog/exec-once.c tests/main.c tests/userprog/exec-arg_SRC = tests/userprog/exec-arg.c tests/main.c +tests/userprog/exec-bound_SRC = tests/userprog/exec-bound.c \ +tests/userprog/boundary.c tests/main.c +tests/userprog/exec-bound-2_SRC = tests/userprog/exec-bound-2.c \ +tests/userprog/boundary.c tests/main.c +tests/userprog/exec-bound-3_SRC = tests/userprog/exec-bound-3.c \ +tests/userprog/boundary.c tests/main.c tests/userprog/exec-multiple_SRC = tests/userprog/exec-multiple.c tests/main.c tests/userprog/exec-missing_SRC = tests/userprog/exec-missing.c tests/main.c tests/userprog/exec-bad-ptr_SRC = tests/userprog/exec-bad-ptr.c tests/main.c @@ -127,6 +136,7 @@ tests/userprog/wait-simple_PUTFILES += tests/userprog/child-simple tests/userprog/wait-twice_PUTFILES += tests/userprog/child-simple tests/userprog/exec-arg_PUTFILES += tests/userprog/child-args +tests/userprog/exec-bound_PUTFILES += tests/userprog/child-args tests/userprog/multi-child-fd_PUTFILES += tests/userprog/child-close tests/userprog/wait-killed_PUTFILES += tests/userprog/child-bad tests/userprog/rox-child_PUTFILES += tests/userprog/child-rox diff --git a/src/tests/userprog/boundary.c b/src/tests/userprog/boundary.c index 59907ec..2e81df4 100644 --- a/src/tests/userprog/boundary.c +++ b/src/tests/userprog/boundary.c @@ -31,3 +31,14 @@ copy_string_across_boundary (const char *src) return p; } +/* Returns an address that is invalid, but the preceding bytes + * are all valid. Used to position information such that the + * first byte of the information is valid, but not all the + * information is valid. */ +void * +get_bad_boundary (void) +{ + /* This code assumes that dst will be in the highest page + * allocated to the user process. */ + return (void *) ROUND_UP ((uintptr_t) (dst + sizeof(dst) - 1), 4096); +} diff --git a/src/tests/userprog/boundary.h b/src/tests/userprog/boundary.h index c8e4b3b..9fadb50 100644 --- a/src/tests/userprog/boundary.h +++ b/src/tests/userprog/boundary.h @@ -3,5 +3,6 @@ void *get_boundary_area (void); char *copy_string_across_boundary (const char *); +void *get_bad_boundary (void); #endif /* tests/userprog/boundary.h */ diff --git a/src/tests/userprog/exec-bound-2.c b/src/tests/userprog/exec-bound-2.c new file mode 100644 index 0000000..7ebed61 --- /dev/null +++ b/src/tests/userprog/exec-bound-2.c @@ -0,0 +1,20 @@ +/* Invokes an exec system call with the exec string pointer argument + positioned such that only its first byte is valid memory (bytes 1-3 + of the pointer are invalid). Must kill process. */ + +#include +#include "tests/userprog/boundary.h" +#include "tests/lib.h" +#include "tests/main.h" + +void +test_main (void) +{ + char *p = get_bad_boundary () - 5; + *((int *) p) = SYS_EXEC; + p[4] = '!'; + + /* Invoke the system call. */ + asm volatile ("movl %0, %%esp; int $0x30" : : "g" (p)); + fail ("should have killed process"); +} diff --git a/src/tests/userprog/exec-bound-2.ck b/src/tests/userprog/exec-bound-2.ck new file mode 100644 index 0000000..0be2946 --- /dev/null +++ b/src/tests/userprog/exec-bound-2.ck @@ -0,0 +1,9 @@ +# -*- perl -*- +use strict; +use warnings; +use tests::tests; +check_expected ([<<'EOF']); +(exec-bound-2) begin +exec-bound-2: exit(-1) +EOF +pass; diff --git a/src/tests/userprog/exec-bound-3.c b/src/tests/userprog/exec-bound-3.c new file mode 100644 index 0000000..67937c8 --- /dev/null +++ b/src/tests/userprog/exec-bound-3.c @@ -0,0 +1,18 @@ +/* Invokes an exec system call with the exec string straddling a + page boundary such that the first byte of the string is valid + but the remainder of the string is in invalid memory. Must + kill process. */ + +#include +#include "tests/userprog/boundary.h" +#include "tests/lib.h" +#include "tests/main.h" + +void +test_main (void) +{ + char *p = get_bad_boundary () - 1; + *p = 'a'; + exec(p); + fail ("should have killed process"); +} diff --git a/src/tests/userprog/exec-bound-3.ck b/src/tests/userprog/exec-bound-3.ck new file mode 100644 index 0000000..93fed65 --- /dev/null +++ b/src/tests/userprog/exec-bound-3.ck @@ -0,0 +1,9 @@ +# -*- perl -*- +use strict; +use warnings; +use tests::tests; +check_expected ([<<'EOF']); +(exec-bound-3) begin +exec-bound-3: exit(-1) +EOF +pass; diff --git a/src/tests/userprog/exec-bound.c b/src/tests/userprog/exec-bound.c new file mode 100644 index 0000000..07a0366 --- /dev/null +++ b/src/tests/userprog/exec-bound.c @@ -0,0 +1,12 @@ +/* Exec a child with an exec string that spans a page boundary. */ + +#include +#include "tests/userprog/boundary.h" +#include "tests/lib.h" +#include "tests/main.h" + +void +test_main (void) +{ + wait (exec (copy_string_across_boundary("child-args arg1 arg2"))); +} diff --git a/src/tests/userprog/exec-bound.ck b/src/tests/userprog/exec-bound.ck new file mode 100644 index 0000000..62e588f --- /dev/null +++ b/src/tests/userprog/exec-bound.ck @@ -0,0 +1,18 @@ +# -*- perl -*- +use strict; +use warnings; +use tests::tests; +check_expected ([<<'EOF']); +(exec-bound) begin +(args) begin +(args) argc = 3 +(args) argv[0] = 'child-args' +(args) argv[1] = 'arg1' +(args) argv[2] = 'arg2' +(args) argv[3] = null +(args) end +child-args: exit(0) +(exec-bound) end +exec-bound: exit(0) +EOF +pass; diff --git a/src/tests/userprog/sc-boundary-3.c b/src/tests/userprog/sc-boundary-3.c new file mode 100644 index 0000000..b2e24ca --- /dev/null +++ b/src/tests/userprog/sc-boundary-3.c @@ -0,0 +1,20 @@ +/* Invokes a system call with the system call number positioned + such that its first byte is valid but the remaining bytes of + the number are in invalid memory. Must kill process. */ + +#include +#include "tests/userprog/boundary.h" +#include "tests/lib.h" +#include "tests/main.h" + +void +test_main (void) +{ + char *p = get_bad_boundary (); + p--; + *p = 100; + + /* Invoke the system call. */ + asm volatile ("movl %0, %%esp; int $0x30" : : "g" (p)); + fail ("should have killed process"); +} diff --git a/src/tests/userprog/sc-boundary-3.ck b/src/tests/userprog/sc-boundary-3.ck new file mode 100644 index 0000000..a7ac8c3 --- /dev/null +++ b/src/tests/userprog/sc-boundary-3.ck @@ -0,0 +1,9 @@ +# -*- perl -*- +use strict; +use warnings; +use tests::tests; +check_expected ([<<'EOF']); +(sc-boundary-3) begin +sc-boundary-3: exit(-1) +EOF +pass; -- 2.30.2