diff --git a/kernel/syscall.c b/kernel/syscall.c index 66ab98d9..d3c0f6f4 100644 --- a/kernel/syscall.c +++ b/kernel/syscall.c @@ -2146,11 +2146,9 @@ SYSCALL_DECLARE(execve) { int error; long ret; - char *empty_envp[1] = {NULL}; const char *filename = (const char *)ihk_mc_syscall_arg0(ctx); char **argv = (char **)ihk_mc_syscall_arg1(ctx); - char **envp = (char **)ihk_mc_syscall_arg2(ctx) ? - (char **)ihk_mc_syscall_arg2(ctx) : empty_envp; + char **envp = (char **)ihk_mc_syscall_arg2(ctx); char *argv_flat = NULL; int argv_flat_len = 0; @@ -2210,7 +2208,7 @@ SYSCALL_DECLARE(execve) /* Flatten argv and envp into kernel-space buffers */ argv_flat_len = flatten_strings_from_user(-1, (desc->shell_path[0] ? desc->shell_path : NULL), argv, &argv_flat); - if (argv_flat_len == 0) { + if (argv_flat_len < 0) { char *kfilename; int len = strlen_user(filename); @@ -2220,12 +2218,12 @@ SYSCALL_DECLARE(execve) kprintf("ERROR: no argv for executable: %s?\n", kfilename? kfilename: ""); if(kfilename) kfree(kfilename); - ret = -EINVAL; + ret = argv_flat_len; goto end; } envp_flat_len = flatten_strings_from_user(-1, NULL, envp, &envp_flat); - if (envp_flat_len == 0) { + if (envp_flat_len < 0) { char *kfilename; int len = strlen_user(filename); @@ -2235,7 +2233,7 @@ SYSCALL_DECLARE(execve) kprintf("ERROR: no envp for executable: %s?\n", kfilename? kfilename: ""); if(kfilename) kfree(kfilename); - ret = -EINVAL; + ret = envp_flat_len; goto end; } diff --git a/lib/string.c b/lib/string.c index 8977747f..ab194e27 100644 --- a/lib/string.c +++ b/lib/string.c @@ -280,6 +280,18 @@ int flatten_strings_from_user(int nr_strings, char *first, char **strings, char long r; int n, ret; + /* When strings is NULL, make array one NULL */ + if (!strings) { + full_len = sizeof(long) + sizeof(char *); + _flat = kmalloc(full_len, IHK_MC_AP_NOWAIT); + if (!_flat) { + return -ENOMEM; + } + memset(_flat, 0, full_len); + *flat = (char *)_flat; + return full_len; + } + /* How many strings do we have? */ if (nr_strings == -1) { nr_strings = 0;