From 9cb18f56fdee6885884f5f08bd5335a42d9034dc Mon Sep 17 00:00:00 2001 From: Jim Meyering Date: Tue, 3 Jul 2007 12:40:20 +0200 Subject: [PATCH 1/4] 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 Signed-off-by: Junio C Hamano --- sha1_file.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/sha1_file.c b/sha1_file.c index b9d07de156..1d328c8d61 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -352,10 +352,14 @@ static void read_info_alternates(const char * relative_base, int depth) char *map; size_t mapsz; struct stat st; - char path[PATH_MAX]; + const char alt_file_name[] = "info/alternates"; + /* Given that relative_base is no longer than PATH_MAX, + ensure that "path" has enough space to append "/", the + file name, "info/alternates", and a trailing NUL. */ + char path[PATH_MAX + 1 + sizeof alt_file_name]; int fd; - sprintf(path, "%s/info/alternates", relative_base); + sprintf(path, "%s/%s", relative_base, alt_file_name); fd = open(path, O_RDONLY); if (fd < 0) return; @@ -814,7 +818,10 @@ void install_packed_git(struct packed_git *pack) static void prepare_packed_git_one(char *objdir, int local) { - char path[PATH_MAX]; + /* Ensure that this buffer is large enough so that we can + append "/pack/" without clobbering the stack even if + strlen(objdir) were PATH_MAX. */ + char path[PATH_MAX + 1 + 4 + 1 + 1]; int len; DIR *dir; struct dirent *de; @@ -836,6 +843,9 @@ static void prepare_packed_git_one(char *objdir, int local) if (!has_extension(de->d_name, ".idx")) continue; + if (len + namelen + 1 > sizeof(path)) + continue; + /* Don't reopen a pack we already have. */ strcpy(path + len, de->d_name); for (p = packed_git; p; p = p->next) { From 3cb567386d5d0349bfb5e3aaf85e973faf685dda Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Tue, 3 Jul 2007 16:01:06 +0100 Subject: [PATCH 2/4] diff --no-index: fix --name-status with added files Without this patch, an added file would be reported as /dev/null. Noticed by David Kastrup. Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- diff.c | 3 ++- t/t4013-diff-various.sh | 2 ++ t/t4013/diff.diff_--name-status_dir2_dir | 3 +++ 3 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 t/t4013/diff.diff_--name-status_dir2_dir diff --git a/diff.c b/diff.c index dc6da5e253..da992dd485 100644 --- a/diff.c +++ b/diff.c @@ -2407,7 +2407,8 @@ static void diff_flush_raw(struct diff_filepair *p, printf("%s ", diff_unique_abbrev(p->two->sha1, abbrev)); } - printf("%s%c%s", status, inter_name_termination, path_one); + printf("%s%c%s", status, inter_name_termination, + two_paths || p->one->mode ? path_one : path_two); if (two_paths) printf("%c%s", inter_name_termination, path_two); putchar(line_termination); diff --git a/t/t4013-diff-various.sh b/t/t4013-diff-various.sh index 8f4c29a6b5..4e7d68dda2 100755 --- a/t/t4013-diff-various.sh +++ b/t/t4013-diff-various.sh @@ -17,6 +17,7 @@ test_expect_success setup ' export GIT_AUTHOR_DATE GIT_COMMITTER_DATE && mkdir dir && + mkdir dir2 && for i in 1 2 3; do echo $i; done >file0 && for i in A B; do echo $i; done >dir/sub && cat file0 >file2 && @@ -252,6 +253,7 @@ diff --patch-with-stat initial..side diff --patch-with-raw initial..side diff --patch-with-stat -r initial..side diff --patch-with-raw -r initial..side +diff --name-status dir2 dir EOF test_done diff --git a/t/t4013/diff.diff_--name-status_dir2_dir b/t/t4013/diff.diff_--name-status_dir2_dir new file mode 100644 index 0000000000..ef7fdb7335 --- /dev/null +++ b/t/t4013/diff.diff_--name-status_dir2_dir @@ -0,0 +1,3 @@ +$ git diff --name-status dir2 dir +A dir/sub +$ From f8d6957628e222bb9f2090c4900f9994559532e1 Mon Sep 17 00:00:00 2001 From: Johannes Schindelin Date: Tue, 3 Jul 2007 21:28:24 +0100 Subject: [PATCH 3/4] glossary: add 'reflog' Signed-off-by: Johannes Schindelin Signed-off-by: Junio C Hamano --- Documentation/glossary.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Documentation/glossary.txt b/Documentation/glossary.txt index e903abfeb8..3f7b1e42b5 100644 --- a/Documentation/glossary.txt +++ b/Documentation/glossary.txt @@ -330,6 +330,12 @@ This commit is referred to as a "merge commit", or sometimes just a denotes a particular <>. These may be stored in `$GIT_DIR/refs/`. +[[def_reflog]]reflog:: + A reflog shows the local "history" of a ref. In other words, + it can tell you what the 3rd last revision in _this_ repository + was, and what was the current state in _this_ repository, + yesterday 9:14pm. See gitlink:git-reflog[1] for details. + [[def_refspec]]refspec:: A "refspec" is used by <> and <> to describe the mapping between remote From ed5f07a6fdc5653e24a5bd6c216d12bc878496bd Mon Sep 17 00:00:00 2001 From: Miklos Vajna Date: Wed, 4 Jul 2007 01:38:29 +0200 Subject: [PATCH 4/4] Document - for git-format-patch The - option was not mentioned in git-format-patch's manpage till now. Fix this. Signed-off-by: Miklos Vajna Signed-off-by: Junio C Hamano --- Documentation/git-format-patch.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Documentation/git-format-patch.txt b/Documentation/git-format-patch.txt index a33d157b97..0ca58a7eb3 100644 --- a/Documentation/git-format-patch.txt +++ b/Documentation/git-format-patch.txt @@ -50,6 +50,9 @@ OPTIONS ------- include::diff-options.txt[] +-:: + Limits the number of patches to prepare. + -o|--output-directory :: Use to store the resulting files, instead of the current working directory.