Being lazy to rely on the cycling N buffers mkpath() and friends return is nice in general, but it makes it too easy to introduce new bugs that are "mysterious". Introduction of read_ref() in create_symref() after calling git_path() to get the git_HEAD value (i.e. the path to create a new symref at) consumed more than the available buffers and broke a later call to mkpath() that derives lockpath from it. Signed-off-by: Junio C Hamano <junkio@xxxxxxx> --- * t7201-co.sh caught three failures. The problem this patch is fixing overwrote and gave ".lock" in lockpath, then open() on that path failed and gave fd = -1 (because I scratched my head and re-run the test without cleaning, and O_EXCL triggered), which threw write_in_full() into infinite loop, which will be fixed with the next patch. refs.c | 20 +++++++++++--------- 1 files changed, 11 insertions(+), 9 deletions(-) diff --git a/refs.c b/refs.c index 5913185..4a52308 100644 --- a/refs.c +++ b/refs.c @@ -992,7 +992,7 @@ int create_symref(const char *ref_target, const char *refs_heads_master, const char *lockpath; char ref[1000]; int fd, len, written; - const char *git_HEAD = git_path("%s", ref_target); + char *git_HEAD = xstrdup(git_path("%s", ref_target)); unsigned char old_sha1[20], new_sha1[20]; if (logmsg && read_ref(ref_target, old_sha1)) @@ -1010,36 +1010,38 @@ int create_symref(const char *ref_target, const char *refs_heads_master, len = snprintf(ref, sizeof(ref), "ref: %s\n", refs_heads_master); if (sizeof(ref) <= len) { error("refname too long: %s", refs_heads_master); - return -1; + goto error_free_return; } lockpath = mkpath("%s.lock", git_HEAD); fd = open(lockpath, O_CREAT | O_EXCL | O_WRONLY, 0666); if (fd < 0) { error("Unable to open %s for writing", lockpath); - return -5; + goto error_free_return; } written = write_in_full(fd, ref, len); close(fd); if (written != len) { - unlink(lockpath); error("Unable to write to %s", lockpath); - return -2; + goto error_unlink_return; } if (rename(lockpath, git_HEAD) < 0) { - unlink(lockpath); error("Unable to create %s", git_HEAD); - return -3; + goto error_unlink_return; } if (adjust_shared_perm(git_HEAD)) { - unlink(lockpath); error("Unable to fix permissions on %s", lockpath); - return -4; + error_unlink_return: + unlink(lockpath); + error_free_return: + free(git_HEAD); + return -1; } done: if (logmsg && !read_ref(refs_heads_master, new_sha1)) log_ref_write(ref_target, old_sha1, new_sha1, logmsg); + free(git_HEAD); return 0; } -- 1.5.0.rc2.g8ac6-dirty - To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html