From f514ef9787f320287d7ba71f2965127b9d8b3832 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Wed, 19 Aug 2015 14:12:37 -0400 Subject: [PATCH 1/8] verify_absent: allow filenames longer than PATH_MAX When unpack-trees wants to know whether a path will overwrite anything in the working tree, we use lstat() to see if there is anything there. But if we are going to write "foo/bar", we can't just lstat("foo/bar"); we need to look for leading prefixes (e.g., "foo"). So we use the lstat cache to find the length of the leading prefix, and copy the filename up to that length into a temporary buffer (since the original name is const, we cannot just stick a NUL in it). The copy we make goes into a PATH_MAX-sized buffer, which will overflow if the prefix is longer than PATH_MAX. How this happens is a little tricky, since in theory PATH_MAX is the biggest path we will have read from the filesystem. But this can happen if: - the compiled-in PATH_MAX does not accurately reflect what the filesystem is capable of - the leading prefix is not _quite_ what is on disk; it contains the next element from the name we are checking. So if we want to write "aaa/bbb/ccc/ddd" and "aaa/bbb" exists, the prefix of interest is "aaa/bbb/ccc". If "aaa/bbb" approaches PATH_MAX, then "ccc" can overflow it. So this can be triggered, but it's hard to do. In particular, you cannot just "git clone" a bogus repo. The verify_absent checks happen before unpack-trees writes anything to the filesystem, so there are never any leading prefixes during the initial checkout, and the bug doesn't trigger. And by definition, these files are larger than PATH_MAX, so writing them will fail, and clone will complain (though it may write a partial path, which will cause a subsequent "git checkout" to hit the bug). We can fix it by creating the temporary path on the heap. The extra malloc overhead is not important, as we are already making at least one stat() call (and probably more for the prefix discovery). Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- unpack-trees.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/unpack-trees.c b/unpack-trees.c index 256df47b35..4a6347899c 100644 --- a/unpack-trees.c +++ b/unpack-trees.c @@ -1432,15 +1432,18 @@ static int verify_absent_1(const struct cache_entry *ce, if (!len) return 0; else if (len > 0) { - char path[PATH_MAX + 1]; - memcpy(path, ce->name, len); - path[len] = 0; - if (lstat(path, &st)) - return error("cannot stat '%s': %s", path, - strerror(errno)); + char *path; + int ret; - return check_ok_to_remove(path, len, DT_UNKNOWN, NULL, &st, - error_type, o); + path = xmemdupz(ce->name, len); + if (lstat(path, &st)) + ret = error("cannot stat '%s': %s", path, + strerror(errno)); + else + ret = check_ok_to_remove(path, len, DT_UNKNOWN, NULL, + &st, error_type, o); + free(path); + return ret; } else if (lstat(ce->name, &st)) { if (errno != ENOENT) return error("cannot stat '%s': %s", ce->name, From c29edfefb6f6a3fef80172c16bcc34c826d417b0 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Wed, 19 Aug 2015 14:12:41 -0400 Subject: [PATCH 2/8] notes: use a strbuf in add_non_note When we are loading a notes tree into our internal hash table, we also collect any files that are clearly non-notes. We format the name of the file into a PATH_MAX buffer, but unlike true notes (which cannot be larger than a fanned-out sha1 hash), these tree entries can be arbitrarily long, overflowing our buffer. We can fix this by switching to a strbuf. It doesn't even cost us an extra allocation, as we can simply hand ownership of the buffer over to the non-note struct. This is of moderate security interest, as you might fetch notes trees from an untrusted remote. However, we do not do so by default, so you would have to manually fetch into the notes namespace. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- notes.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/notes.c b/notes.c index 5fe691dbcd..6a9cc6295b 100644 --- a/notes.c +++ b/notes.c @@ -362,13 +362,14 @@ static int non_note_cmp(const struct non_note *a, const struct non_note *b) return strcmp(a->path, b->path); } -static void add_non_note(struct notes_tree *t, const char *path, +/* note: takes ownership of path string */ +static void add_non_note(struct notes_tree *t, char *path, unsigned int mode, const unsigned char *sha1) { struct non_note *p = t->prev_non_note, *n; n = (struct non_note *) xmalloc(sizeof(struct non_note)); n->next = NULL; - n->path = xstrdup(path); + n->path = path; n->mode = mode; hashcpy(n->sha1, sha1); t->prev_non_note = n; @@ -482,17 +483,17 @@ handle_non_note: * component. */ { - char non_note_path[PATH_MAX]; - char *p = non_note_path; + struct strbuf non_note_path = STRBUF_INIT; const char *q = sha1_to_hex(subtree->key_sha1); int i; for (i = 0; i < prefix_len; i++) { - *p++ = *q++; - *p++ = *q++; - *p++ = '/'; + strbuf_addch(&non_note_path, *q++); + strbuf_addch(&non_note_path, *q++); + strbuf_addch(&non_note_path, '/'); } - strcpy(p, entry.path); - add_non_note(t, non_note_path, entry.mode, entry.sha1); + strbuf_addstr(&non_note_path, entry.path); + add_non_note(t, strbuf_detach(&non_note_path, NULL), + entry.mode, entry.sha1); } } free(buf); From 5015f01c12a45a1042c1aa6b6f7f6b62bfa00ade Mon Sep 17 00:00:00 2001 From: Jeff King Date: Wed, 19 Aug 2015 14:12:45 -0400 Subject: [PATCH 3/8] read_info_alternates: handle paths larger than PATH_MAX This function assumes that the relative_base path passed into it is no larger than PATH_MAX, and writes into a fixed-size buffer. However, this path may not have actually come from the filesystem; for example, add_submodule_odb generates a path using a strbuf and passes it in. This is hard to trigger in practice, though, because the long submodule directory would have to exist on disk before we would try to open its info/alternates file. We can easily avoid the bug, though, by simply creating the filename on the heap. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- sha1_file.c | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/sha1_file.c b/sha1_file.c index d7f1838c13..b231b62784 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -377,15 +377,12 @@ void read_info_alternates(const char * relative_base, int depth) char *map; size_t mapsz; struct stat st; - 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]; + char *path; int fd; - sprintf(path, "%s/%s", relative_base, alt_file_name); + path = xstrfmt("%s/info/alternates", relative_base); fd = git_open_noatime(path); + free(path); if (fd < 0) return; if (fstat(fd, &st) || (st.st_size == 0)) { From 78f23bdf68dae56d644892990484951583a64014 Mon Sep 17 00:00:00 2001 From: Jeff King Date: Wed, 19 Aug 2015 14:12:48 -0400 Subject: [PATCH 4/8] show-branch: use a strbuf for reflog descriptions When we show "branch@{0}", we format into a fixed-size buffer using sprintf. This can overflow if you have long branch names. We can fix it by using a temporary strbuf. Signed-off-by: Jeff King Signed-off-by: Junio C Hamano --- builtin/show-branch.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/builtin/show-branch.c b/builtin/show-branch.c index 270e39c6c1..9e60b12445 100644 --- a/builtin/show-branch.c +++ b/builtin/show-branch.c @@ -720,7 +720,6 @@ int cmd_show_branch(int ac, const char **av, const char *prefix) if (reflog) { unsigned char sha1[20]; - char nth_desc[256]; char *ref; int base = 0; unsigned int flags = 0; @@ -759,6 +758,7 @@ int cmd_show_branch(int ac, const char **av, const char *prefix) for (i = 0; i < reflog; i++) { char *logmsg; + char *nth_desc; const char *msg; unsigned long timestamp; int tz; @@ -777,8 +777,10 @@ int cmd_show_branch(int ac, const char **av, const char *prefix) show_date(timestamp, tz, 1), msg); free(logmsg); - sprintf(nth_desc, "%s@{%d}", *av, base+i); + + nth_desc = xstrfmt("%s@{%d}", *av, base+i); append_ref(nth_desc, sha1, 1); + free(nth_desc); } free(ref); } From 441c4a40173fe1ee8a5c0094e587dfc47e2a6460 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 4 Sep 2015 10:25:47 -0700 Subject: [PATCH 5/8] Git 2.2.3 Signed-off-by: Junio C Hamano --- Documentation/RelNotes/2.2.3.txt | 9 +++++++++ Documentation/git.txt | 3 ++- GIT-VERSION-GEN | 2 +- RelNotes | 2 +- 4 files changed, 13 insertions(+), 3 deletions(-) create mode 100644 Documentation/RelNotes/2.2.3.txt diff --git a/Documentation/RelNotes/2.2.3.txt b/Documentation/RelNotes/2.2.3.txt new file mode 100644 index 0000000000..5bfffa4106 --- /dev/null +++ b/Documentation/RelNotes/2.2.3.txt @@ -0,0 +1,9 @@ +Git v2.2.3 Release Notes +======================== + +Fixes since v2.2.2 +------------------ + + * A handful of codepaths that used to use fixed-sized arrays to hold + pathnames have been corrected to use strbuf and other mechanisms to + allow longer pathnames without fearing overflows. diff --git a/Documentation/git.txt b/Documentation/git.txt index edceb50866..577d634491 100644 --- a/Documentation/git.txt +++ b/Documentation/git.txt @@ -43,9 +43,10 @@ unreleased) version of Git, that is available from the 'master' branch of the `git.git` repository. Documentation for older releases are available here: -* link:v2.2.2/git.html[documentation for release 2.2.2] +* link:v2.2.3/git.html[documentation for release 2.2.3] * release notes for + link:RelNotes/2.2.3.txt[2.2.3], link:RelNotes/2.2.2.txt[2.2.2], link:RelNotes/2.2.1.txt[2.2.1], link:RelNotes/2.2.0.txt[2.2]. diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN index f9f8f32740..71d66e4fae 100755 --- a/GIT-VERSION-GEN +++ b/GIT-VERSION-GEN @@ -1,7 +1,7 @@ #!/bin/sh GVF=GIT-VERSION-FILE -DEF_VER=v2.2.2 +DEF_VER=v2.2.3 LF=' ' diff --git a/RelNotes b/RelNotes index c5fa3efb98..bc5f54365d 120000 --- a/RelNotes +++ b/RelNotes @@ -1 +1 @@ -Documentation/RelNotes/2.2.2.txt \ No newline at end of file +Documentation/RelNotes/2.2.3.txt \ No newline at end of file From ecad27cf98c391d5cfdc26ce0e442e02347baad0 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 4 Sep 2015 10:31:34 -0700 Subject: [PATCH 6/8] Git 2.3.9 Signed-off-by: Junio C Hamano --- Documentation/RelNotes/2.3.9.txt | 9 +++++++++ Documentation/git.txt | 3 ++- GIT-VERSION-GEN | 2 +- RelNotes | 2 +- 4 files changed, 13 insertions(+), 3 deletions(-) create mode 100644 Documentation/RelNotes/2.3.9.txt diff --git a/Documentation/RelNotes/2.3.9.txt b/Documentation/RelNotes/2.3.9.txt new file mode 100644 index 0000000000..1a2ad3235a --- /dev/null +++ b/Documentation/RelNotes/2.3.9.txt @@ -0,0 +1,9 @@ +Git v2.3.9 Release Notes +======================== + +Fixes since v2.3.8 +------------------ + + * A handful of codepaths that used to use fixed-sized arrays to hold + pathnames have been corrected to use strbuf and other mechanisms to + allow longer pathnames without fearing overflows. diff --git a/Documentation/git.txt b/Documentation/git.txt index 9c46cabcb9..a62ed6f11a 100644 --- a/Documentation/git.txt +++ b/Documentation/git.txt @@ -43,9 +43,10 @@ unreleased) version of Git, that is available from the 'master' branch of the `git.git` repository. Documentation for older releases are available here: -* link:v2.3.8/git.html[documentation for release 2.3.8] +* link:v2.3.9/git.html[documentation for release 2.3.9] * release notes for + link:RelNotes/2.3.9.txt[2.3.9], link:RelNotes/2.3.8.txt[2.3.8], link:RelNotes/2.3.7.txt[2.3.7], link:RelNotes/2.3.6.txt[2.3.6], diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN index a2fe57a6ac..7577f66e97 100755 --- a/GIT-VERSION-GEN +++ b/GIT-VERSION-GEN @@ -1,7 +1,7 @@ #!/bin/sh GVF=GIT-VERSION-FILE -DEF_VER=v2.3.8 +DEF_VER=v2.3.9 LF=' ' diff --git a/RelNotes b/RelNotes index 159d09e820..2f2927a251 120000 --- a/RelNotes +++ b/RelNotes @@ -1 +1 @@ -Documentation/RelNotes/2.3.8.txt \ No newline at end of file +Documentation/RelNotes/2.3.9.txt \ No newline at end of file From 74b67638166ca2e66497ede559dbf393e7af8b40 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 4 Sep 2015 10:36:00 -0700 Subject: [PATCH 7/8] Git 2.4.9 Signed-off-by: Junio C Hamano --- Documentation/RelNotes/2.4.9.txt | 9 +++++++++ Documentation/git.txt | 3 ++- GIT-VERSION-GEN | 2 +- RelNotes | 2 +- 4 files changed, 13 insertions(+), 3 deletions(-) create mode 100644 Documentation/RelNotes/2.4.9.txt diff --git a/Documentation/RelNotes/2.4.9.txt b/Documentation/RelNotes/2.4.9.txt new file mode 100644 index 0000000000..09af9ddbc7 --- /dev/null +++ b/Documentation/RelNotes/2.4.9.txt @@ -0,0 +1,9 @@ +Git v2.4.9 Release Notes +======================== + +Fixes since v2.4.9 +------------------ + + * A handful of codepaths that used to use fixed-sized arrays to hold + pathnames have been corrected to use strbuf and other mechanisms to + allow longer pathnames without fearing overflows. diff --git a/Documentation/git.txt b/Documentation/git.txt index a8740b994b..97d9fb41b2 100644 --- a/Documentation/git.txt +++ b/Documentation/git.txt @@ -43,9 +43,10 @@ unreleased) version of Git, that is available from the 'master' branch of the `git.git` repository. Documentation for older releases are available here: -* link:v2.4.8/git.html[documentation for release 2.4.8] +* link:v2.4.9/git.html[documentation for release 2.4.9] * release notes for + link:RelNotes/2.4.9.txt[2.4.9], link:RelNotes/2.4.8.txt[2.4.8], link:RelNotes/2.4.7.txt[2.4.7], link:RelNotes/2.4.6.txt[2.4.6], diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN index a6a0bf9aa7..38e296b311 100755 --- a/GIT-VERSION-GEN +++ b/GIT-VERSION-GEN @@ -1,7 +1,7 @@ #!/bin/sh GVF=GIT-VERSION-FILE -DEF_VER=v2.4.8 +DEF_VER=v2.4.9 LF=' ' diff --git a/RelNotes b/RelNotes index b5645b3f74..3e8a59f846 120000 --- a/RelNotes +++ b/RelNotes @@ -1 +1 @@ -Documentation/RelNotes/2.4.8.txt \ No newline at end of file +Documentation/RelNotes/2.4.9.txt \ No newline at end of file From 27ea6f85beff1173ec74349fa35c45951feee570 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 4 Sep 2015 10:46:00 -0700 Subject: [PATCH 8/8] Git 2.5.2 Signed-off-by: Junio C Hamano --- Documentation/RelNotes/2.5.2.txt | 63 ++++++++++++++++++++++++++++++++ Documentation/git.txt | 3 +- GIT-VERSION-GEN | 2 +- RelNotes | 2 +- 4 files changed, 67 insertions(+), 3 deletions(-) create mode 100644 Documentation/RelNotes/2.5.2.txt diff --git a/Documentation/RelNotes/2.5.2.txt b/Documentation/RelNotes/2.5.2.txt new file mode 100644 index 0000000000..3f749398bb --- /dev/null +++ b/Documentation/RelNotes/2.5.2.txt @@ -0,0 +1,63 @@ +Git v2.5.2 Release Notes +======================== + +Fixes since v2.5.1 +------------------ + + * "git init empty && git -C empty log" said "bad default revision 'HEAD'", + which was found to be a bit confusing to new users. + + * The "interpret-trailers" helper mistook a multi-paragraph title of + a commit log message with a colon in it as the end of the trailer + block. + + * When re-priming the cache-tree opportunistically while committing + the in-core index as-is, we mistakenly invalidated the in-core + index too aggressively, causing the experimental split-index code + to unnecessarily rewrite the on-disk index file(s). + + * "git archive" did not use zip64 extension when creating an archive + with more than 64k entries, which nobody should need, right ;-)? + + * The code in "multiple-worktree" support that attempted to recover + from an inconsistent state updated an incorrect file. + + * "git rev-list" does not take "--notes" option, but did not complain + when one is given. + + * Because the configuration system does not allow "alias.0foo" and + "pager.0foo" as the configuration key, the user cannot use '0foo' + as a custom command name anyway, but "git 0foo" tried to look these + keys up and emitted useless warnings before saying '0foo is not a + git command'. These warning messages have been squelched. + + * We recently rewrote one of the build scripts in Perl, which made it + necessary to have Perl to build Git. Reduced Perl dependency by + rewriting it again using sed. + + * t1509 test that requires a dedicated VM environment had some + bitrot, which has been corrected. + + * strbuf_read() used to have one extra iteration (and an unnecessary + strbuf_grow() of 8kB), which was eliminated. + + * The codepath to produce error messages had a hard-coded limit to + the size of the message, primarily to avoid memory allocation while + calling die(). + + * When trying to see that an object does not exist, a state errno + leaked from our "first try to open a packfile with O_NOATIME and + then if it fails retry without it" logic on a system that refuses + O_NOATIME. This confused us and caused us to die, saying that the + packfile is unreadable, when we should have just reported that the + object does not exist in that packfile to the caller. + + * An off-by-one error made "git remote" to mishandle a remote with a + single letter nickname. + + * A handful of codepaths that used to use fixed-sized arrays to hold + pathnames have been corrected to use strbuf and other mechanisms to + allow longer pathnames without fearing overflows. + +Also contains typofixes, documentation updates and trivial code +clean-ups. diff --git a/Documentation/git.txt b/Documentation/git.txt index 3b5573d191..629e62c925 100644 --- a/Documentation/git.txt +++ b/Documentation/git.txt @@ -43,9 +43,10 @@ unreleased) version of Git, that is available from the 'master' branch of the `git.git` repository. Documentation for older releases are available here: -* link:v2.5.1/git.html[documentation for release 2.5.1] +* link:v2.5.2/git.html[documentation for release 2.5.2] * release notes for + link:RelNotes/2.5.2.txt[2.5.2], link:RelNotes/2.5.1.txt[2.5.1], link:RelNotes/2.5.0.txt[2.5]. diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN index 5e23aba39c..9e3723eee3 100755 --- a/GIT-VERSION-GEN +++ b/GIT-VERSION-GEN @@ -1,7 +1,7 @@ #!/bin/sh GVF=GIT-VERSION-FILE -DEF_VER=v2.5.1 +DEF_VER=v2.5.2 LF=' ' diff --git a/RelNotes b/RelNotes index 171969f9ef..24f83fe617 120000 --- a/RelNotes +++ b/RelNotes @@ -1 +1 @@ -Documentation/RelNotes/2.5.1.txt \ No newline at end of file +Documentation/RelNotes/2.5.2.txt \ No newline at end of file