diff --git a/README b/README
index c46ec2a06f4b77f7d7a524e5330efa69beb39f38..3ea05a7ee5fb14e5147f4aff4d816641e46df6e4 100644
--- a/README
+++ b/README
@@ -20,8 +20,8 @@ The following people made contributions:
     Cliff Frey (MP)
     Xiao Yu (MP)
 
-In addition, we are grateful for the patches submitted by Greg Price,
-Yandong Mao, and Hitoshi Mitake.
+In addition, we are grateful for the patches contributed by Greg
+Price, Yandong Mao, and Hitoshi Mitake.
 
 The code in the files that constitute xv6 is
 Copyright 2006-2007 Frans Kaashoek, Robert Morris, and Russ Cox.
diff --git a/usertests.c b/usertests.c
index 670a4a8e3d691464783607a66027d0aa5e4cd0ca..7ec03fcb57c720158976d91cee6d134e684d9e5e 100644
--- a/usertests.c
+++ b/usertests.c
@@ -324,6 +324,7 @@ mem(void)
   void *m1, *m2;
   int pid, ppid;
 
+  printf(1, "mem test\n");
   ppid = getpid();
   if((pid = fork()) == 0){
     m1 = 0;
@@ -1332,6 +1333,41 @@ sbrktest(void)
     wait();
   }
 
+  // if we run the system out of memory, does it clean up the last
+  // failed allocation?
+  sbrk(-(sbrk(0) - oldbrk));
+  int pids[32];
+  int fds[2];
+  if(pipe(fds) != 0){
+    printf(1, "pipe() failed\n");
+    exit();
+  }
+  for (i = 0; i < sizeof(pids)/sizeof(pids[0]); i++){
+    if ((pids[i] = fork()) == 0) {
+      // allocate the full 640K
+      sbrk((640 * 1024) - (uint)sbrk(0));
+      write(fds[1], "x", 1);
+      // sit around until killed
+      while (1) sleep(1000);
+    }
+    char scratch;
+    if (pids[i] != -1)
+      read(fds[0], &scratch, 1);
+  }
+  // if those failed allocations freed up the pages they did allocate,
+  // we'll be able to allocate here
+  c = sbrk(4096);
+  for (i = 0; i < sizeof(pids)/sizeof(pids[0]); i++){
+    if (pids[i] == -1)
+      continue;
+    kill(pids[i]);
+    wait();
+  }
+  if (c == (char*)0xffffffff) {
+    printf(stdout, "failed sbrk leaked memory\n");
+    exit();
+  }
+
   if(sbrk(0) > oldbrk)
     sbrk(-(sbrk(0) - oldbrk));
 
diff --git a/vm.c b/vm.c
index 8a57ca9d901c1ac143d2f3f3f52280b571d5a338..95eeca8e3fb9096361930b98da7d0d1dd0732cbd 100644
--- a/vm.c
+++ b/vm.c
@@ -195,7 +195,8 @@ allocuvm(pde_t *pgdir, char *addr, uint sz)
     if(pte == 0 || (*pte & PTE_P) == 0){
       char *mem = kalloc();
       if(mem == 0){
-        // XXX clean up?
+        cprintf("allocuvm out of memory\n");
+        deallocuvm(pgdir, addr, sz);
         return 0;
       }
       memset(mem, 0, PGSIZE);