示例#1
0
static int
copy_kargv(struct mm_struct *mm, char **kargv, const char **argv, int max_argc,
	   int *argc_store)
{
	int i, ret = -E_INVAL;
	if (!argv) {
		*argc_store = 0;
		return 0;
	}
	char *argv_k;
	for (i = 0; i < max_argc; i++) {
		if (!copy_from_user(mm, &argv_k, argv + i, sizeof(char *), 0))
			goto failed_cleanup;
		if (!argv_k)
			break;
		char *buffer;
		if ((buffer = kmalloc(EXEC_MAX_ARG_LEN + 1)) == NULL) {
			goto failed_nomem;
		}
#if 0
		if (!copy_from_user(mm, &argv_k, argv + i, sizeof(char *), 0) ||
		    !copy_string(mm, buffer, argv_k, EXEC_MAX_ARG_LEN + 1)) {
			kfree(buffer);
			goto failed_cleanup;
		}
#endif
		if (!copy_string(mm, buffer, argv_k, EXEC_MAX_ARG_LEN + 1)) {
			kfree(buffer);
			goto failed_cleanup;
		}
		kargv[i] = buffer;
	}
	*argc_store = i;
	return 0;

failed_nomem:
	ret = -E_NO_MEM;
failed_cleanup:
	put_kargv(i, kargv);
	return ret;
}
示例#2
0
int
do_execve(const char *filename, const char **argv, const char **envp) {
    static_assert(EXEC_MAX_ARG_LEN >= FS_MAX_FPATH_LEN);
    
    struct mm_struct *mm = current->mm;

    char local_name[PROC_NAME_LEN + 1];
    memset(local_name, 0, sizeof(local_name));

    char *kargv[EXEC_MAX_ARG_NUM], *kenvp[EXEC_MAX_ENV_NUM];
    const char *path;

    int ret = -E_INVAL;
    lock_mm(mm);
#if 0
    if (name == NULL) {
        snprintf(local_name, sizeof(local_name), "<null> %d", current->pid);
    }
    else {
        if (!copy_string(mm, local_name, name, sizeof(local_name))) {
            unlock_mm(mm);
            return ret;
        }
    }
#endif
    snprintf(local_name, sizeof(local_name), "<null> %d", current->pid);

    int argc = 0, envc = 0;
    if ((ret = copy_kargv(mm, kargv, argv, EXEC_MAX_ARG_NUM, &argc)) != 0) {
      unlock_mm(mm);
      return ret;
    }
    if ((ret = copy_kargv(mm, kenvp, envp, EXEC_MAX_ENV_NUM, &envc)) != 0) {
      unlock_mm(mm);
      put_kargv(argc, kargv);
      return ret;
    }

#if 0
    int i;
    kprintf("## fn %s\n", filename);
    kprintf("## argc %d\n", argc);
    for(i=0;i<argc;i++)
      kprintf("## %08x %s\n", kargv[i], kargv[i]);
    kprintf("## envc %d\n", envc);
    for(i=0;i<envc;i++)
      kprintf("## %08x %s\n", kenvp[i], kenvp[i]);
#endif
    //path = argv[0];
    //copy_from_user (mm, &path, argv, sizeof (char*), 0);
    path = filename;
    unlock_mm(mm);

    /* linux never do this */
    //fs_closeall(current->fs_struct);

    /* sysfile_open will check the first argument path, thus we have to use a user-space pointer, and argv[0] may be incorrect */

    int fd;
    if ((ret = fd = sysfile_open(path, O_RDONLY)) < 0) {
      goto execve_exit;
    }

    if (mm != NULL) {
      mm->lapic = -1;
      mp_set_mm_pagetable(NULL);
      if (mm_count_dec(mm) == 0) {
        exit_mmap(mm);
        put_pgdir(mm);
        bool intr_flag;
        local_intr_save(intr_flag);
        {
          list_del(&(mm->proc_mm_link));
        }
            local_intr_restore(intr_flag);
            mm_destroy(mm);
        }
        current->mm = NULL;
    }
    put_sem_queue(current);

    ret = -E_NO_MEM;
    /* init signal */
    put_sighand(current);
    if ((current->signal_info.sighand = sighand_create()) == NULL) {
      goto execve_exit;
    }
    sighand_count_inc(current->signal_info.sighand);

    put_signal(current);
    if ((current->signal_info.signal = signal_create()) == NULL) {
      goto execve_exit;
    }
    signal_count_inc(current->signal_info.signal);

    if ((current->sem_queue = sem_queue_create()) == NULL) {
      goto execve_exit;
    }
    sem_queue_count_inc(current->sem_queue);

    if ((ret = load_icode(fd, argc, kargv, envc, kenvp)) != 0) {
      goto execve_exit;
    }

    set_proc_name(current, local_name);

	if (do_execve_arch_hook (argc, kargv) < 0)
		goto execve_exit;
	
    put_kargv(argc, kargv);
    return 0;

execve_exit:
    put_kargv(argc, kargv);
    put_kargv(envc, kenvp);
/* exec should return -1 if failed */
    //return ret;
    do_exit(ret);
    panic("already exit: %e.\n", ret);
}