Save and restore user processes' FS and GS registers.
[pintos-anon] / src / userprog / process.c
index 36c1bd0582437d280e630788d605ab9f87409bd1..c0a6547acb0e09a7717d43ab8fb7199e8ae7248b 100644 (file)
@@ -54,6 +54,8 @@ execute_thread (void *filename_)
 
   /* Initialize interrupt frame and load executable. */
   memset (&if_, 0, sizeof if_);
+  if_.gs = SEL_UDSEG;
+  if_.fs = SEL_UDSEG;
   if_.es = SEL_UDSEG;
   if_.ds = SEL_UDSEG;
   if_.cs = SEL_UCSEG;
@@ -75,10 +77,7 @@ execute_thread (void *filename_)
      arguments on the stack in the form of a `struct intr_frame',
      we just point the stack pointer (%esp) to our stack frame
      and jump to it. */
-  asm ("mov %0, %%esp\n"
-       "jmp intr_exit\n"
-       : /* no outputs */
-       : "g" (&if_));
+  asm ("mov %%esp, %0; jmp intr_exit" :: "g" (&if_));
   NOT_REACHED ();
 }
 
@@ -227,7 +226,7 @@ load (const char *filename, void (**eip) (void), void **esp)
   if (ehdr.e_machine != 3)
     LOAD_ERROR (("ELF executable is not x86"));
   if (ehdr.e_version != 1)
-    LOAD_ERROR (("ELF executable hasunknown version %d",
+    LOAD_ERROR (("ELF executable has unknown version %d",
                  (int) ehdr.e_version));
   if (ehdr.e_phentsize != sizeof (struct Elf32_Phdr))
     LOAD_ERROR (("bad ELF program header size"));
@@ -240,7 +239,10 @@ load (const char *filename, void (**eip) (void), void **esp)
     {
       struct Elf32_Phdr phdr;
 
+      if (file_ofs < 0 || file_ofs > file_length (file))
+        LOAD_ERROR (("bad file offset %ld", (long) file_ofs));
       file_seek (file, file_ofs);
+
       if (file_read (file, &phdr, sizeof phdr) != sizeof phdr)
         LOAD_ERROR (("error reading program header"));
       file_ofs += sizeof phdr;
@@ -316,6 +318,13 @@ load_segment (struct file *file, const struct Elf32_Phdr *phdr)
       return false; 
     }
 
+  /* p_offset must point within file. */
+  if (phdr->p_offset > (Elf32_Off) file_length (file)) 
+    {
+      printf ("bad p_offset %"PE32Ox, phdr->p_offset);
+      return false;
+    }
+
   /* [ELF1] 2-3 says that p_memsz must be at least as big as
      p_filesz. */
   if (phdr->p_memsz < phdr->p_filesz)