mirror of
https://github.com/git/git
synced 2024-11-05 18:59:29 +00:00
execv_git_cmd: Fix stack buffer overflow.
Signed-off-by: Dmitry V. Levin <ldv@altlinux.org> Signed-off-by: Junio C Hamano <junkio@cox.net>
This commit is contained in:
parent
347f1d2608
commit
d685990101
1 changed files with 23 additions and 9 deletions
30
exec_cmd.c
30
exec_cmd.c
|
@ -32,12 +32,14 @@ const char *git_exec_path(void)
|
||||||
int execv_git_cmd(const char **argv)
|
int execv_git_cmd(const char **argv)
|
||||||
{
|
{
|
||||||
char git_command[PATH_MAX + 1];
|
char git_command[PATH_MAX + 1];
|
||||||
int len, i;
|
int i;
|
||||||
const char *paths[] = { current_exec_path,
|
const char *paths[] = { current_exec_path,
|
||||||
getenv("GIT_EXEC_PATH"),
|
getenv("GIT_EXEC_PATH"),
|
||||||
builtin_exec_path };
|
builtin_exec_path };
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_SIZE(paths); ++i) {
|
for (i = 0; i < ARRAY_SIZE(paths); ++i) {
|
||||||
|
size_t len;
|
||||||
|
int rc;
|
||||||
const char *exec_dir = paths[i];
|
const char *exec_dir = paths[i];
|
||||||
const char *tmp;
|
const char *tmp;
|
||||||
|
|
||||||
|
@ -46,8 +48,9 @@ int execv_git_cmd(const char **argv)
|
||||||
if (*exec_dir != '/') {
|
if (*exec_dir != '/') {
|
||||||
if (!getcwd(git_command, sizeof(git_command))) {
|
if (!getcwd(git_command, sizeof(git_command))) {
|
||||||
fprintf(stderr, "git: cannot determine "
|
fprintf(stderr, "git: cannot determine "
|
||||||
"current directory\n");
|
"current directory: %s\n",
|
||||||
exit(1);
|
strerror(errno));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
len = strlen(git_command);
|
len = strlen(git_command);
|
||||||
|
|
||||||
|
@ -57,17 +60,28 @@ int execv_git_cmd(const char **argv)
|
||||||
while (*exec_dir == '/')
|
while (*exec_dir == '/')
|
||||||
exec_dir++;
|
exec_dir++;
|
||||||
}
|
}
|
||||||
snprintf(git_command + len, sizeof(git_command) - len,
|
|
||||||
"/%s", exec_dir);
|
rc = snprintf(git_command + len,
|
||||||
|
sizeof(git_command) - len, "/%s",
|
||||||
|
exec_dir);
|
||||||
|
if (rc < 0 || rc >= sizeof(git_command) - len) {
|
||||||
|
fprintf(stderr, "git: command name given "
|
||||||
|
"is too long.\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
|
if (strlen(exec_dir) + 1 > sizeof(git_command)) {
|
||||||
|
fprintf(stderr, "git: command name given "
|
||||||
|
"is too long.\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
strcpy(git_command, exec_dir);
|
strcpy(git_command, exec_dir);
|
||||||
}
|
}
|
||||||
|
|
||||||
len = strlen(git_command);
|
len = strlen(git_command);
|
||||||
len += snprintf(git_command + len, sizeof(git_command) - len,
|
rc = snprintf(git_command + len, sizeof(git_command) - len,
|
||||||
"/git-%s", argv[0]);
|
"/git-%s", argv[0]);
|
||||||
|
if (rc < 0 || rc >= sizeof(git_command) - len) {
|
||||||
if (sizeof(git_command) <= len) {
|
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"git: command name given is too long.\n");
|
"git: command name given is too long.\n");
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in a new issue