+The kernel must treat user memory delicately. As part of a system
+call, the user can pass to the kernel a null pointer, a pointer to
+unmapped virtual memory, or a pointer to kernel virtual address space
+(above @code{PHYS_BASE}). All of these types of invalid pointers must
+be rejected without harm to the kernel or other running processes. At
+your option, the kernel may handle invalid pointers by terminating the
+process or returning from the system call with an error.
+
+There are at least two reasonable ways to do this correctly. The
+first method is to ``verify then access'':@footnote{These terms are
+made up for this document. They are not standard terminology.} verify
+the validity of a user-provided pointer, then dereference it. If you
+choose this route, you'll want to look at the functions in
+@file{userprog/pagedir.c} and in @file{threads/mmu.h}. This is the
+simplest way to handle user memory access.
+
+The second method is to ``assume and react'': directly dereference
+user pointers, after checking that they point below @code{PHYS_BASE}.
+Invalid user pointers will then cause a ``page fault'' that you can
+handle by modifying the code for @code{page_fault()} in
+@file{userprog/exception.cc}. This technique is normally faster
+because it takes advantage of the processor's MMU, so it tends to be
+used in real kernels (including Linux).
+
+In either case, you need to make sure not to ``leak'' resources. For
+example, suppose that your system call has acquired a lock or
+allocated a page of memory. If you encounter an invalid user pointer
+afterward, you must still be sure to release the lock or free the page
+of memory. If you choose to ``verify then access,'' then this should
+be straightforward, but for ``assume and react'' it's more difficult,
+because there's no way to return an error code from a memory access.
+Therefore, for those who want to try the latter technique, we'll
+provide a little bit of helpful code: