Converts sys_exec / proc_create to use umem
authorBarret Rhoden <brho@cs.berkeley.edu>
Mon, 26 Jul 2010 23:05:05 +0000 (16:05 -0700)
committerKevin Klues <klueska@cs.berkeley.edu>
Thu, 3 Nov 2011 00:35:49 +0000 (17:35 -0700)
Also fixes a bug with dynamically linked binaries not starting properly
if they were sys_proc_create()d.  The arguments need to be set before
loading the elf, which can be fixed if we come up with a good way to do
argument passing.

kern/include/umem.h
kern/src/syscall.c
kern/src/umem.c
tests/spawn.c

index 15837b5..77396fc 100644 (file)
@@ -23,6 +23,7 @@ int memcpy_from_user(struct proc *p, void *dest, const void *DANGEROUS va,
 int memcpy_to_user(struct proc *p, void *DANGEROUS va, const void *src,
                    size_t len);
 /* Same as above, but sets errno */
+int memcpy_from_user_errno(struct proc *p, void *dst, const void *src, int len);
 int memcpy_to_user_errno(struct proc *p, void *dst, const void *src, int len);
                  
 /* Creates a buffer (kmalloc) and safely copies into it from va.  Can return an
index 6f61df4..90556e8 100644 (file)
@@ -206,33 +206,33 @@ static int sys_proc_create(struct proc *p, char *path, size_t path_l,
        struct proc *new_p;
 
        /* Copy in the path.  Consider putting an upper bound. */
-       t_path = kmalloc(path_l, 0);
-       if (!t_path) {
-               set_errno(current_tf, ENOMEM);
+       t_path = user_strdup_errno(p, path, path_l);
+       if (IS_ERR(t_path))
                return -1;
-       }
-       if (memcpy_from_user(p, t_path, path, path_l)) {
-               kfree(t_path);
-               set_errno(current_tf, EINVAL);
-               return -1;
-       }
        program = path_to_file(t_path);
-       kfree(t_path);
+       user_memdup_free(p, t_path);
        if (!program)
                return -1;                      /* presumably, errno is already set */
-       new_p = proc_create(program, 0, 0);
+       /* TODO: need to split the proc creation, since you must load after setting
+        * args/env, since auxp gets set up there. */
+       //new_p = proc_create(program, 0, 0);
+       if (proc_alloc(&new_p, current))
+               return -1;
        /* Set the argument stuff needed by glibc */
-       if (memcpy_from_user(p, new_p->procinfo->argp, pi->argp, sizeof(pi->argp))){
+       if (memcpy_from_user_errno(p, new_p->procinfo->argp, pi->argp,
+                                  sizeof(pi->argp))) {
                atomic_dec(&program->f_refcnt); /* TODO: REF */
                proc_destroy(new_p);
-               set_errno(current_tf, EINVAL);
                return -1;
        }
-       if (memcpy_from_user(p, new_p->procinfo->argbuf, pi->argbuf,
-                            sizeof(pi->argbuf))) {
+       if (memcpy_from_user_errno(p, new_p->procinfo->argbuf, pi->argbuf,
+                                  sizeof(pi->argbuf))) {
                atomic_dec(&program->f_refcnt); /* TODO: REF */
                proc_destroy(new_p);
-               set_errno(current_tf, EINVAL);
+               return -1;
+       }
+       if (load_elf(new_p, program)) {
+               proc_destroy(new_p);
                return -1;
        }
        pid = new_p->pid;
@@ -400,30 +400,22 @@ static int sys_exec(struct proc *p, char *path, size_t path_l,
        if(p->state != PROC_RUNNING_S)
                return -1;
        /* Copy in the path.  Consider putting an upper bound. */
-       t_path = kmalloc(path_l, 0);
-       if (!t_path) {
-               set_errno(current_tf, ENOMEM);
+       t_path = user_strdup_errno(p, path, path_l);
+       if (IS_ERR(t_path))
                return -1;
-       }
-       if (memcpy_from_user(p, t_path, path, path_l)) {
-               kfree(t_path);
-               set_errno(current_tf, EINVAL);
-               return -1;
-       }
        program = path_to_file(t_path);
-       kfree(t_path);
+       user_memdup_free(p, t_path);
        if (!program)
                return -1;                      /* presumably, errno is already set */
        /* Set the argument stuff needed by glibc */
-       if (memcpy_from_user(p, p->procinfo->argp, pi->argp, sizeof(pi->argp))) {
+       if (memcpy_from_user_errno(p, p->procinfo->argp, pi->argp,
+                                  sizeof(pi->argp))) {
                atomic_dec(&program->f_refcnt); /* TODO: REF */
-               set_errno(current_tf, EINVAL);
                return -1;
        }
-       if (memcpy_from_user(p, p->procinfo->argbuf, pi->argbuf,
-                            sizeof(pi->argbuf))) {
+       if (memcpy_from_user_errno(p, p->procinfo->argbuf, pi->argbuf,
+                                  sizeof(pi->argbuf))) {
                atomic_dec(&program->f_refcnt); /* TODO: REF */
-               set_errno(current_tf, EINVAL);
                return -1;
        }
        /* This is the point of no return for the process. */
index 483d9aa..5263d15 100644 (file)
@@ -186,6 +186,16 @@ int memcpy_from_user(struct proc *p, void *dest, const void *DANGEROUS va,
        return 0;
 }
 
+/* Same as above, but sets errno */
+int memcpy_from_user_errno(struct proc *p, void *dst, const void *src, int len)
+{
+       if (memcpy_from_user(p, dst, src, len)) {
+               set_errno(current_tf, EINVAL);
+               return -1;
+       }
+       return 0;
+}
+
 /**
  * @brief Copies data to a user buffer from a kernel buffer.
  * 
@@ -240,6 +250,7 @@ int memcpy_to_user(struct proc *p, void *va, const void *src, size_t len)
        return 0;
 }
 
+/* Same as above, but sets errno */
 int memcpy_to_user_errno(struct proc *p, void *dst, const void *src, int len)
 {
        if (memcpy_to_user(p, dst, src, len)) {
index 766b38f..f46d4e0 100644 (file)
@@ -2,7 +2,7 @@
 #include <rstdio.h>
 #include <parlib.h>
 
-int main(int argc, char** argv)
+int main(int argc, char **argv, char **envp)
 {
        #define FILENAME "/bin/hello"
        #if 0
@@ -36,6 +36,7 @@ int main(int argc, char** argv)
        else
                if (sys_proc_run(child_pid[0]) < 0)
                        perror("");
+       #if 0
        printf("U: attempting to create and run another hello\n");
        child_pid[1] = sys_proc_create(FILENAME, strlen(FILENAME), 0, 0);
        if (child_pid[1] <= 0)
@@ -43,5 +44,6 @@ int main(int argc, char** argv)
        else
                if (sys_proc_run(child_pid[1]) < 0)
                        perror("");
+       #endif
        return 0;
 }