git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Thomas Rast <trast@student.ethz.ch>
To: Junio C Hamano <gitster@pobox.com>
Cc: <git@vger.kernel.org>, Pierre Habouzit <madcoder@debian.org>
Subject: [PATCH] strbuf_grow(): maintain nul-termination even for new buffer
Date: Mon, 29 Aug 2011 23:16:12 +0200	[thread overview]
Message-ID: <c8d8686c1813885a36d8f4cada218686989df236.1314651926.git.trast@student.ethz.ch> (raw)

In the case where sb is initialized to the slopbuf (through
strbuf_init(sb,0) or STRBUF_INIT), strbuf_grow() loses the terminating
nul: it grows the buffer, but gives ALLOC_GROW a NULL source to avoid
it being freed.  So ALLOC_GROW does not copy anything to the new
memory area.

This subtly broke the call to strbuf_getline in read_next_command()
[fast-import.c:1855], which goes

    strbuf_detach(&command_buf, NULL);  # command_buf is now = STRBUF_INIT
    stdin_eof = strbuf_getline(&command_buf, stdin, '\n');
    if (stdin_eof)
            return EOF;

In strbuf_getwholeline, this did

    strbuf_grow(sb, 0);  # loses nul-termination
    if (feof(fp))
            return EOF;
    strbuf_reset(sb);    # this would have nul-terminated!

Valgrind found this because fast-import subsequently uses prefixcmp()
on command_buf.buf, which after the EOF exit contains only
uninitialized memory.

Arguably strbuf_getwholeline is also broken, in that it touches the
buffer before deciding whether to do any work.  However, it seems more
futureproof to not let the strbuf API lose the nul-termination by its
own fault.

So make sure that strbuf_grow() puts in a nul even if it has nowhere
to copy it from.  This makes strbuf_grow(sb, 0) a semantic no-op as
far as readers of the buffer are concerned.

Also remove the nul-termination added by strbuf_init, which is made
redudant.

Signed-off-by: Thomas Rast <trast@student.ethz.ch>
---

Only found this now because the bug is only triggered by the tests
added in 4cedb78 (fast-import: add input format tests, 2011-08-11).


 strbuf.c |    9 +++++----
 1 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/strbuf.c b/strbuf.c
index 1a7df12..4556f96 100644
--- a/strbuf.c
+++ b/strbuf.c
@@ -30,10 +30,8 @@ void strbuf_init(struct strbuf *sb, size_t hint)
 {
 	sb->alloc = sb->len = 0;
 	sb->buf = strbuf_slopbuf;
-	if (hint) {
+	if (hint)
 		strbuf_grow(sb, hint);
-		sb->buf[0] = '\0';
-	}
 }
 
 void strbuf_release(struct strbuf *sb)
@@ -65,12 +63,15 @@ void strbuf_attach(struct strbuf *sb, void *buf, size_t len, size_t alloc)
 
 void strbuf_grow(struct strbuf *sb, size_t extra)
 {
+	int new_buf = !sb->alloc;
 	if (unsigned_add_overflows(extra, 1) ||
 	    unsigned_add_overflows(sb->len, extra + 1))
 		die("you want to use way too much memory");
-	if (!sb->alloc)
+	if (new_buf)
 		sb->buf = NULL;
 	ALLOC_GROW(sb->buf, sb->len + extra + 1, sb->alloc);
+	if (new_buf)
+		sb->buf[0] = '\0';
 }
 
 void strbuf_trim(struct strbuf *sb)
-- 
1.7.7.rc0.370.gdcae57

             reply	other threads:[~2011-08-29 21:16 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-08-29 21:16 Thomas Rast [this message]
2011-08-29 22:41 ` [PATCH] strbuf_grow(): maintain nul-termination even for new buffer Erik Faye-Lund
2011-08-29 23:09 ` Junio C Hamano
2011-08-29 23:15 ` Brandon Casey

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=c8d8686c1813885a36d8f4cada218686989df236.1314651926.git.trast@student.ethz.ch \
    --to=trast@student.ethz.ch \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=madcoder@debian.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).