@matheusbsbs / matheus-bagliano / commits / 620e2bb937
Fork 0

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>

Dmitry Potapov committed Jul 16, 2008 at 19:33 UTC 620e2bb93785ed8eb60846d94fd4753d4817c8ec
1 file changed +15 -12
builtin-grep.c
+15 -12
@@ -427,33 +427,35 @@ static int grep_tree(struct grep_opt *opt, const char **paths,
427 struct name_entry entry;
428 char *down;
429 int tn_len = strlen(tree_name);
430 - char *path_buf = xmalloc(PATH_MAX + tn_len + 100);
430 + struct strbuf pathbuf;
431 +
432 + strbuf_init(&pathbuf, PATH_MAX + tn_len);
433
434 if (tn_len) {
433 - tn_len = sprintf(path_buf, "%s:", tree_name);
434 - down = path_buf + tn_len;
435 - strcat(down, base);
436 - }
437 - else {
438 - down = path_buf;
439 - strcpy(down, base);
435 + strbuf_add(&pathbuf, tree_name, tn_len);
436 + strbuf_addch(&pathbuf, ':');
437 + tn_len = pathbuf.len;
438 }
441 - len = strlen(path_buf);
439 + strbuf_addstr(&pathbuf, base);
440 + len = pathbuf.len;
441
442 while (tree_entry(tree, &entry)) {
444 - strcpy(path_buf + len, entry.path);
443 + int te_len = tree_entry_len(entry.path, entry.sha1);
444 + pathbuf.len = len;
445 + strbuf_add(&pathbuf, entry.path, te_len);
446
447 if (S_ISDIR(entry.mode))
448 /* Match "abc/" against pathspec to
449 * decide if we want to descend into "abc"
450 * directory.
451 */
451 - strcpy(path_buf + len + tree_entry_len(entry.path, entry.sha1), "/");
452 + strbuf_addch(&pathbuf, '/');
453
454 + down = pathbuf.buf + tn_len;
455 if (!pathspec_matches(paths, down))
456 ;
457 else if (S_ISREG(entry.mode))
456 - hit |= grep_sha1(opt, entry.sha1, path_buf, tn_len);
458 + hit |= grep_sha1(opt, entry.sha1, pathbuf.buf, tn_len);
459 else if (S_ISDIR(entry.mode)) {
460 enum object_type type;
461 struct tree_desc sub;
@@ -469,6 +471,7 @@ static int grep_tree(struct grep_opt *opt, const char **paths,
471 free(data);
472 }
473 }
474 + strbuf_release(&pathbuf);
475 return hit;
476 }
477