merge branch 'pr-1982'
nsexec (CVE-2019-5736): avoid parsing environ LGTMs: @cyphar @crosbymichael Closes #1982
This commit is contained in:
commit
751f18de2a
|
@ -169,31 +169,25 @@ static int parse_xargs(char *data, int data_length, char ***output)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* "Parse" out argv and envp from /proc/self/cmdline and /proc/self/environ.
|
* "Parse" out argv from /proc/self/cmdline.
|
||||||
* This is necessary because we are running in a context where we don't have a
|
* This is necessary because we are running in a context where we don't have a
|
||||||
* main() that we can just get the arguments from.
|
* main() that we can just get the arguments from.
|
||||||
*/
|
*/
|
||||||
static int fetchve(char ***argv, char ***envp)
|
static int fetchve(char ***argv)
|
||||||
{
|
{
|
||||||
char *cmdline = NULL, *environ = NULL;
|
char *cmdline = NULL;
|
||||||
size_t cmdline_size, environ_size;
|
size_t cmdline_size;
|
||||||
|
|
||||||
cmdline = read_file("/proc/self/cmdline", &cmdline_size);
|
cmdline = read_file("/proc/self/cmdline", &cmdline_size);
|
||||||
if (!cmdline)
|
if (!cmdline)
|
||||||
goto error;
|
goto error;
|
||||||
environ = read_file("/proc/self/environ", &environ_size);
|
|
||||||
if (!environ)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
if (parse_xargs(cmdline, cmdline_size, argv) <= 0)
|
if (parse_xargs(cmdline, cmdline_size, argv) <= 0)
|
||||||
goto error;
|
goto error;
|
||||||
if (parse_xargs(environ, environ_size, envp) <= 0)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
error:
|
error:
|
||||||
free(environ);
|
|
||||||
free(cmdline);
|
free(cmdline);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
@ -246,23 +240,26 @@ error:
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Get cheap access to the environment. */
|
||||||
|
extern char **environ;
|
||||||
|
|
||||||
int ensure_cloned_binary(void)
|
int ensure_cloned_binary(void)
|
||||||
{
|
{
|
||||||
int execfd;
|
int execfd;
|
||||||
char **argv = NULL, **envp = NULL;
|
char **argv = NULL;
|
||||||
|
|
||||||
/* Check that we're not self-cloned, and if we are then bail. */
|
/* Check that we're not self-cloned, and if we are then bail. */
|
||||||
int cloned = is_self_cloned();
|
int cloned = is_self_cloned();
|
||||||
if (cloned > 0 || cloned == -ENOTRECOVERABLE)
|
if (cloned > 0 || cloned == -ENOTRECOVERABLE)
|
||||||
return cloned;
|
return cloned;
|
||||||
|
|
||||||
if (fetchve(&argv, &envp) < 0)
|
if (fetchve(&argv) < 0)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
execfd = clone_binary();
|
execfd = clone_binary();
|
||||||
if (execfd < 0)
|
if (execfd < 0)
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
|
||||||
fexecve(execfd, argv, envp);
|
fexecve(execfd, argv, environ);
|
||||||
return -ENOEXEC;
|
return -ENOEXEC;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue