Added more userprog tests, mostly relating to boundary conditions
authorJohn Ousterhout <ouster@cs.stanford.edu>
Fri, 14 Dec 2012 22:51:09 +0000 (14:51 -0800)
committerJohn Ousterhout <ouster@cs.stanford.edu>
Thu, 17 Dec 2015 17:31:29 +0000 (09:31 -0800)
involving invalid pages (e.g., position system call opcode with first
bytes in a valid page and remaining bytes in a nonexistent page).

12 files changed:
src/tests/Make.tests
src/tests/userprog/Make.tests
src/tests/userprog/boundary.c
src/tests/userprog/boundary.h
src/tests/userprog/exec-bound-2.c [new file with mode: 0644]
src/tests/userprog/exec-bound-2.ck [new file with mode: 0644]
src/tests/userprog/exec-bound-3.c [new file with mode: 0644]
src/tests/userprog/exec-bound-3.ck [new file with mode: 0644]
src/tests/userprog/exec-bound.c [new file with mode: 0644]
src/tests/userprog/exec-bound.ck [new file with mode: 0644]
src/tests/userprog/sc-boundary-3.c [new file with mode: 0644]
src/tests/userprog/sc-boundary-3.ck [new file with mode: 0644]

index 358e69724b156b15dc98c76301367015ee3b6a59..32494ca104f3c62056e24b69bb3e845e3619a0d4 100644 (file)
@@ -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 =
index caadd90edbef093b184e682841f182b335eef99e..a60b1f048758e3a1f11361a53f47affd581d2e4e 100644 (file)
@@ -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
index 59907ec935d36d8e498766730138741f0143e89d..2e81df48e0beb5c75489e6bdb8c781c39b771213 100644 (file)
@@ -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);
+}
index c8e4b3ba01f23270b7f8afc6804b7e0eb3c964e5..9fadb5054ad61246a1ce86b1b514b8ffc9a927fc 100644 (file)
@@ -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 (file)
index 0000000..7ebed61
--- /dev/null
@@ -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 <syscall-nr.h>
+#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 (file)
index 0000000..0be2946
--- /dev/null
@@ -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 (file)
index 0000000..67937c8
--- /dev/null
@@ -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 <syscall-nr.h>
+#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 (file)
index 0000000..93fed65
--- /dev/null
@@ -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 (file)
index 0000000..07a0366
--- /dev/null
@@ -0,0 +1,12 @@
+/* Exec a child with an exec string that spans a page boundary. */
+
+#include <syscall.h>
+#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 (file)
index 0000000..62e588f
--- /dev/null
@@ -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 (file)
index 0000000..b2e24ca
--- /dev/null
@@ -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 <syscall-nr.h>
+#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 (file)
index 0000000..a7ac8c3
--- /dev/null
@@ -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;