u32 procwrap_load(union trapped_args *args, void *pr_ctxt) { s32 i, len; int status = 0; char *temp; s32 count = args->args_proc_load.argc_index; u8 **argv = NULL, **envp = NULL; void *hprocessor = ((struct process_context *)pr_ctxt)->processor; if (count <= 0 || count > MAX_LOADARGS) { status = -EINVAL; goto func_cont; } argv = kmalloc(count * sizeof(u8 *), GFP_KERNEL); if (!argv) { status = -ENOMEM; goto func_cont; } CP_FM_USR(argv, args->args_proc_load.user_args, status, count); if (status) { kfree(argv); argv = NULL; goto func_cont; } for (i = 0; i < count; i++) { if (argv[i]) { temp = (char *)argv[i]; len = strlen_user((char *)temp) + 1; argv[i] = kmalloc(len, GFP_KERNEL); if (argv[i]) { CP_FM_USR(argv[i], temp, status, len); if (status) { kfree(argv[i]); argv[i] = NULL; goto func_cont; } } else { status = -ENOMEM; goto func_cont; } } } if (args->args_proc_load.user_envp) { count = 0; do { if (get_user(temp, args->args_proc_load.user_envp + count)) { status = -EFAULT; goto func_cont; } count++; } while (temp); envp = kmalloc(count * sizeof(u8 *), GFP_KERNEL); if (!envp) { status = -ENOMEM; goto func_cont; } CP_FM_USR(envp, args->args_proc_load.user_envp, status, count); if (status) { kfree(envp); envp = NULL; goto func_cont; } for (i = 0; envp[i]; i++) { temp = (char *)envp[i]; len = strlen_user((char *)temp) + 1; envp[i] = kmalloc(len, GFP_KERNEL); if (envp[i]) { CP_FM_USR(envp[i], temp, status, len); if (status) { kfree(envp[i]); envp[i] = NULL; goto func_cont; } } else { status = -ENOMEM; goto func_cont; } } } if (!status) { status = proc_load(hprocessor, args->args_proc_load.argc_index, (const char **)argv, (const char **)envp); } func_cont: if (envp) { i = 0; while (envp[i]) kfree(envp[i++]); kfree(envp); } if (argv) { count = args->args_proc_load.argc_index; for (i = 0; (i < count) && argv[i]; i++) kfree(argv[i]); kfree(argv); } return status; }
/* * ======== procwrap_load ======== */ u32 procwrap_load(union trapped_args *args, void *pr_ctxt) { s32 i, len; int status = 0; char *temp; s32 count = args->args_proc_load.argc_index; u8 **argv = NULL, **envp = NULL; void *hprocessor = ((struct process_context *)pr_ctxt)->processor; if (count <= 0 || count > MAX_LOADARGS) { status = -EINVAL; goto func_cont; } argv = kmalloc(count * sizeof(u8 *), GFP_KERNEL); if (!argv) { status = -ENOMEM; goto func_cont; } CP_FM_USR(argv, args->args_proc_load.user_args, status, count); if (status) { kfree(argv); argv = NULL; goto func_cont; } for (i = 0; i < count; i++) { if (argv[i]) { /* User space pointer to argument */ temp = (char *)argv[i]; /* len is increased by 1 to accommodate NULL */ len = strlen_user((char *)temp) + 1; /* Kernel space pointer to argument */ argv[i] = kmalloc(len, GFP_KERNEL); if (argv[i]) { CP_FM_USR(argv[i], temp, status, len); if (status) { kfree(argv[i]); argv[i] = NULL; goto func_cont; } } else { status = -ENOMEM; goto func_cont; } } } /* TODO: validate this */ if (args->args_proc_load.user_envp) { /* number of elements in the envp array including NULL */ count = 0; do { if (get_user(temp, args->args_proc_load.user_envp + count)) { status = -EFAULT; goto func_cont; } count++; } while (temp); envp = kmalloc(count * sizeof(u8 *), GFP_KERNEL); if (!envp) { status = -ENOMEM; goto func_cont; } CP_FM_USR(envp, args->args_proc_load.user_envp, status, count); if (status) { kfree(envp); envp = NULL; goto func_cont; } for (i = 0; envp[i]; i++) { /* User space pointer to argument */ temp = (char *)envp[i]; /* len is increased by 1 to accommodate NULL */ len = strlen_user((char *)temp) + 1; /* Kernel space pointer to argument */ envp[i] = kmalloc(len, GFP_KERNEL); if (envp[i]) { CP_FM_USR(envp[i], temp, status, len); if (status) { kfree(envp[i]); envp[i] = NULL; goto func_cont; } } else { status = -ENOMEM; goto func_cont; } } } if (!status) { status = proc_load(hprocessor, args->args_proc_load.argc_index, (const char **)argv, (const char **)envp); } func_cont: if (envp) { i = 0; while (envp[i]) kfree(envp[i++]); kfree(envp); } if (argv) { count = args->args_proc_load.argc_index; for (i = 0; (i < count) && argv[i]; i++) kfree(argv[i]); kfree(argv); } return status; }