Don't smash stack when $GIT_ALTERNATE_OBJECT_DIRECTORIES is too long
commit9cb18f56fdee6885884f5f08bd5335a42d9034dc
authorJim Meyering <jim@meyering.net>
Tue, 3 Jul 2007 10:40:20 +0000 (3 12:40 +0200)
committerJunio C Hamano <gitster@pobox.com>
Tue, 3 Jul 2007 19:25:29 +0000 (3 12:25 -0700)
tree9af06f4ef04c75a07edeb652255c63b084831e91
parente8964a5b91e13169ad73c7b1db2e904441ad93f5
Don't smash stack when $GIT_ALTERNATE_OBJECT_DIRECTORIES is too long

There is no restriction on the length of the name returned by
get_object_directory, other than the fact that it must be a stat'able
git object directory.  That means its name may have length up to
PATH_MAX-1 (i.e., often 4095) not counting the trailing NUL.

Combine that with the assumption that the concatenation of that name and
suffixes like "/info/alternates" and "/pack/---long-name---.idx" will fit
in a buffer of length PATH_MAX, and you see the problem.  Here's a fix:

    sha1_file.c (prepare_packed_git_one): Lengthen "path" buffer
    so we are guaranteed to be able to append "/pack/" without checking.
    Skip any directory entry that is too long to be appended.
    (read_info_alternates): Protect against a similar buffer overrun.

Before this change, using the following admittedly contrived environment
setting would cause many git commands to clobber their stack and segfault
on a system with PATH_MAX == 4096:

  t=$(perl -e '$s=".git/objects";$n=(4096-6-length($s))/2;print "./"x$n . $s')
  export GIT_ALTERNATE_OBJECT_DIRECTORIES=$t
  touch g
  ./git-update-index --add g

If you run the above commands, you'll soon notice that many
git commands now segfault, so you'll want to do this:

  unset GIT_ALTERNATE_OBJECT_DIRECTORIES

Signed-off-by: Jim Meyering <jim@meyering.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
sha1_file.c