Fix buffer overflow in git-grep

If PATH_MAX on your system is smaller than any path stored in the git
repository, that can cause memory corruption inside of the grep_tree
function used by git-grep.

Signed-off-by: Dmitry Potapov <dpotapov@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Dmitry Potapov
2008-07-16 19:33:29 +04:00
committed by Junio C Hamano
parent df4b3abc94
commit 620e2bb937

View File

@ -427,33 +427,35 @@ static int grep_tree(struct grep_opt *opt, const char **paths,
struct name_entry entry; struct name_entry entry;
char *down; char *down;
int tn_len = strlen(tree_name); int tn_len = strlen(tree_name);
char *path_buf = xmalloc(PATH_MAX + tn_len + 100); struct strbuf pathbuf;
strbuf_init(&pathbuf, PATH_MAX + tn_len);
if (tn_len) { if (tn_len) {
tn_len = sprintf(path_buf, "%s:", tree_name); strbuf_add(&pathbuf, tree_name, tn_len);
down = path_buf + tn_len; strbuf_addch(&pathbuf, ':');
strcat(down, base); tn_len = pathbuf.len;
} }
else { strbuf_addstr(&pathbuf, base);
down = path_buf; len = pathbuf.len;
strcpy(down, base);
}
len = strlen(path_buf);
while (tree_entry(tree, &entry)) { while (tree_entry(tree, &entry)) {
strcpy(path_buf + len, entry.path); int te_len = tree_entry_len(entry.path, entry.sha1);
pathbuf.len = len;
strbuf_add(&pathbuf, entry.path, te_len);
if (S_ISDIR(entry.mode)) if (S_ISDIR(entry.mode))
/* Match "abc/" against pathspec to /* Match "abc/" against pathspec to
* decide if we want to descend into "abc" * decide if we want to descend into "abc"
* directory. * directory.
*/ */
strcpy(path_buf + len + tree_entry_len(entry.path, entry.sha1), "/"); strbuf_addch(&pathbuf, '/');
down = pathbuf.buf + tn_len;
if (!pathspec_matches(paths, down)) if (!pathspec_matches(paths, down))
; ;
else if (S_ISREG(entry.mode)) else if (S_ISREG(entry.mode))
hit |= grep_sha1(opt, entry.sha1, path_buf, tn_len); hit |= grep_sha1(opt, entry.sha1, pathbuf.buf, tn_len);
else if (S_ISDIR(entry.mode)) { else if (S_ISDIR(entry.mode)) {
enum object_type type; enum object_type type;
struct tree_desc sub; struct tree_desc sub;
@ -469,6 +471,7 @@ static int grep_tree(struct grep_opt *opt, const char **paths,
free(data); free(data);
} }
} }
strbuf_release(&pathbuf);
return hit; return hit;
} }