kern: mmap: make the lowest mmap address MiB; mmap ld.so at MiB
authorRonald G. Minnich <rminnich@google.com>
Wed, 30 Jul 2014 19:37:38 +0000 (19:37 +0000)
committerRonald G. Minnich <rminnich@google.com>
Wed, 30 Jul 2014 19:37:38 +0000 (19:37 +0000)
We spent a day debugging a bad pointer that was the wrong bad pointer;
it was actually a data corruption of a null pointer that changed it to
ff00, which was valid memory since we load ld.so at 4k. As it turns out,
it's easier nowadays to get a deref via a NULL pointer struct to not take a fault
if you have anything mapped at anything less than 1M; structs are big.

Map ld.so at MiB; don't allow mappings lower than MiB. This doesn't fix
the go runtime problem, but it would have let us find the issue
several days earlier. And, since this is a common issue, might as well
avoid it in this instance.

Signed-off-by: Ronald G. Minnich <rminnich@google.com>
kern/include/mm.h
kern/src/elf.c

index a58aa3e..04bab7b 100644 (file)
@@ -55,7 +55,7 @@ void print_vmrs(struct proc *p);
 /* mmap() related functions.  These manipulate VMRs and change the hardware page
  * tables.  Any requests below the LOWEST_VA will silently be upped.  This may
  * be a dynamic proc-specific variable later. */
-#define MMAP_LOWEST_VA PGSIZE
+#define MMAP_LOWEST_VA MiB
 void *mmap(struct proc *p, uintptr_t addr, size_t len, int prot, int flags,
            int fd, size_t offset);
 void *do_mmap(struct proc *p, uintptr_t addr, size_t len, int prot, int flags,
index 171fa30..8db3e45 100644 (file)
@@ -266,8 +266,13 @@ int load_elf(struct proc* p, struct file* f)
                struct file *interp = do_file_open(ei.interp, 0, 0);
                if (!interp)
                        return -1;
-               /* Load dynamic linker one page into the address space */
-               int error = load_one_elf(p, interp, 1, &interp_ei, TRUE);
+               /* Load dynamic linker at 1M. Obvious MIB joke avoided.
+                * It used to be loaded at page 1, but the existence of valid addresses
+                * that low masked bad derefs through NULL pointer structs. This in turn
+                * helped us waste a full day debugging a bug in the Go runtime. True!
+                * Note that MMAP_LOWEST_VA also has this value but we want to make this
+                * explicit. */
+               int error = load_one_elf(p, interp, MiB>>12, &interp_ei, TRUE);
                kref_put(&interp->f_kref);
                if (error)
                        return -1;