Fixed bug in reading elf headers
authorBarret Rhoden <brho@cs.berkeley.edu>
Mon, 26 Jul 2010 22:05:50 +0000 (15:05 -0700)
committerKevin Klues <klueska@cs.berkeley.edu>
Thu, 3 Nov 2011 00:35:49 +0000 (17:35 -0700)
Need to be careful about reading or writing a file on behalf of the
kernel.  If current is set, the file read/write will think it is the
user, and fail to write to a kernel buffer.  Marked as TODO: KFOP.

kern/src/elf.c
kern/src/syscall.c
kern/src/vfs.c
tests/spawn.c

index 9232a0e..c749b06 100644 (file)
@@ -34,8 +34,14 @@ load_one_elf(struct proc* p, struct file* f, int pgoffset, elf_info_t* ei)
        // assume program headers fit in a page.
        // if this isn't true, change the code below that maps in program headers
        char* elf = (char*)kmalloc(PGSIZE,0);
+       
+       /* When reading on behalf of the kernel, we need to make sure no proc is
+        * "current".  This is a bit ghetto (TODO: KFOP) */
+       struct proc *cur_proc = current;
+       current = 0;
        if(!elf || f->f_op->read(f, elf, PGSIZE, &f_off) == -1)
                goto fail;
+       current = cur_proc;
 
        elf_t* elfhdr = (elf_t*)elf;
        proghdr_t* proghdrs = (proghdr_t*)(elf+elfhdr->e_phoff);
index daf0704..6f61df4 100644 (file)
@@ -437,7 +437,7 @@ static int sys_exec(struct proc *p, char *path, size_t path_l,
                proc_destroy(p);
                smp_idle();             /* syscall can't return on failure now */
        }
-       printk("[PID %d] exec %s\n", p->pid, file_name(program));
+       printd("[PID %d] exec %s\n", p->pid, file_name(program));
        atomic_dec(&program->f_refcnt);         /* TODO: (REF) / KREF */
        *current_tf = p->env_tf;
        return 0;
index 7aab421..7115c36 100644 (file)
@@ -492,7 +492,10 @@ ssize_t generic_file_read(struct file *file, char *buf, size_t count,
                assert(!error); /* TODO: handle ENOMEM and friends */
                copy_amt = MIN(PGSIZE - page_off, buf_end - buf);
                /* TODO: think about this.  if it's a user buffer, we're relying on
-                * current to detect whose it is (which should work for async calls). */
+                * current to detect whose it is (which should work for async calls).
+                * Also, need to propagate errors properly...  Probably should do a
+                * user_mem_check, then free, and also to make a distinction between
+                * when the kernel wants a read/write (TODO: KFOP) */
                if (current) {
                        memcpy_to_user(current, buf, page2kva(page) + page_off, copy_amt);
                } else {
index 67311c7..766b38f 100644 (file)
@@ -31,9 +31,17 @@ int main(int argc, char** argv)
        #endif
        printf("U: attempting to create and run hello\n");
        child_pid[0] = sys_proc_create(FILENAME, strlen(FILENAME), 0, 0);
-       sys_proc_run(child_pid[0]);
+       if (child_pid[0] <= 0)
+               perror("");
+       else
+               if (sys_proc_run(child_pid[0]) < 0)
+                       perror("");
        printf("U: attempting to create and run another hello\n");
        child_pid[1] = sys_proc_create(FILENAME, strlen(FILENAME), 0, 0);
-       sys_proc_run(child_pid[1]);
+       if (child_pid[1] <= 0)
+               perror("");
+       else
+               if (sys_proc_run(child_pid[1]) < 0)
+                       perror("");
        return 0;
 }