make McKernel's execve behave same as Linux when argv or envp is set to NULL (fix for TEMP_FIX_21)
This commit is contained in:
@ -2146,11 +2146,9 @@ SYSCALL_DECLARE(execve)
|
|||||||
{
|
{
|
||||||
int error;
|
int error;
|
||||||
long ret;
|
long ret;
|
||||||
char *empty_envp[1] = {NULL};
|
|
||||||
const char *filename = (const char *)ihk_mc_syscall_arg0(ctx);
|
const char *filename = (const char *)ihk_mc_syscall_arg0(ctx);
|
||||||
char **argv = (char **)ihk_mc_syscall_arg1(ctx);
|
char **argv = (char **)ihk_mc_syscall_arg1(ctx);
|
||||||
char **envp = (char **)ihk_mc_syscall_arg2(ctx) ?
|
char **envp = (char **)ihk_mc_syscall_arg2(ctx);
|
||||||
(char **)ihk_mc_syscall_arg2(ctx) : empty_envp;
|
|
||||||
|
|
||||||
char *argv_flat = NULL;
|
char *argv_flat = NULL;
|
||||||
int argv_flat_len = 0;
|
int argv_flat_len = 0;
|
||||||
@ -2210,7 +2208,7 @@ SYSCALL_DECLARE(execve)
|
|||||||
/* Flatten argv and envp into kernel-space buffers */
|
/* Flatten argv and envp into kernel-space buffers */
|
||||||
argv_flat_len = flatten_strings_from_user(-1, (desc->shell_path[0] ?
|
argv_flat_len = flatten_strings_from_user(-1, (desc->shell_path[0] ?
|
||||||
desc->shell_path : NULL), argv, &argv_flat);
|
desc->shell_path : NULL), argv, &argv_flat);
|
||||||
if (argv_flat_len == 0) {
|
if (argv_flat_len < 0) {
|
||||||
char *kfilename;
|
char *kfilename;
|
||||||
int len = strlen_user(filename);
|
int len = strlen_user(filename);
|
||||||
|
|
||||||
@ -2220,12 +2218,12 @@ SYSCALL_DECLARE(execve)
|
|||||||
kprintf("ERROR: no argv for executable: %s?\n", kfilename? kfilename: "");
|
kprintf("ERROR: no argv for executable: %s?\n", kfilename? kfilename: "");
|
||||||
if(kfilename)
|
if(kfilename)
|
||||||
kfree(kfilename);
|
kfree(kfilename);
|
||||||
ret = -EINVAL;
|
ret = argv_flat_len;
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
envp_flat_len = flatten_strings_from_user(-1, NULL, envp, &envp_flat);
|
envp_flat_len = flatten_strings_from_user(-1, NULL, envp, &envp_flat);
|
||||||
if (envp_flat_len == 0) {
|
if (envp_flat_len < 0) {
|
||||||
char *kfilename;
|
char *kfilename;
|
||||||
int len = strlen_user(filename);
|
int len = strlen_user(filename);
|
||||||
|
|
||||||
@ -2235,7 +2233,7 @@ SYSCALL_DECLARE(execve)
|
|||||||
kprintf("ERROR: no envp for executable: %s?\n", kfilename? kfilename: "");
|
kprintf("ERROR: no envp for executable: %s?\n", kfilename? kfilename: "");
|
||||||
if(kfilename)
|
if(kfilename)
|
||||||
kfree(kfilename);
|
kfree(kfilename);
|
||||||
ret = -EINVAL;
|
ret = envp_flat_len;
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
12
lib/string.c
12
lib/string.c
@ -280,6 +280,18 @@ int flatten_strings_from_user(int nr_strings, char *first, char **strings, char
|
|||||||
long r;
|
long r;
|
||||||
int n, ret;
|
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? */
|
/* How many strings do we have? */
|
||||||
if (nr_strings == -1) {
|
if (nr_strings == -1) {
|
||||||
nr_strings = 0;
|
nr_strings = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user