All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jeff King <peff@peff.net>
To: "brian m. carlson" <sandals@crustytoothpaste.net>
Cc: git@vger.kernel.org, "Nguyễn Thái Ngọc Duy" <pclouds@gmail.com>,
	"Junio C Hamano" <gitster@pobox.com>
Subject: Re: [PATCH v2 06/21] builtin/receive-pack: fix incorrect pointer arithmetic
Date: Tue, 28 Mar 2017 02:51:23 -0400	[thread overview]
Message-ID: <20170328065123.f4uswxxznv3wyqaz@sigill.intra.peff.net> (raw)
In-Reply-To: <20170326160143.769630-7-sandals@crustytoothpaste.net>

On Sun, Mar 26, 2017 at 04:01:28PM +0000, brian m. carlson wrote:

> If we had already processed the last newline in a push certificate, we
> would end up subtracting NULL from the end-of-certificate pointer when
> computing the length of the line.  This would have resulted in an
> absurdly large length, and possibly a buffer overflow.  Instead,
> subtract the beginning-of-certificate pointer from the
> end-of-certificate pointer, which is what's expected.
> 
> Note that this situation should never occur, since not only do we
> require the certificate to be newline terminated, but the signature will
> only be read from the beginning of a line.  Nevertheless, it seems
> prudent to correct it.

I think you can trigger it with carefully-crafted input. Try this on the
client side:

diff --git a/send-pack.c b/send-pack.c
index 66e652f7e..dd18c9a33 100644
--- a/send-pack.c
+++ b/send-pack.c
@@ -311,8 +311,7 @@ static int generate_push_cert(struct strbuf *req_buf,
 	if (!update_seen)
 		goto free_return;
 
-	if (sign_buffer(&cert, &cert, signing_key))
-		die(_("failed to sign the push certificate"));
+	strbuf_rtrim(&cert);
 
 	packet_buf_write(req_buf, "push-cert%c%s", 0, cap_string);
 	for (cp = cert.buf; cp < cert.buf + cert.len; cp = np) {

We omit the signature entirely, which causes the parser to treat the
end of the string as the end-of-cert (we still find the end because the
push-cert-end is in its own pkt-line; you could also just issue a flush,
which has the same effect).

And then the rtrim means that the cert doesn't actually end in a
newline. Running t5534 with this patch causes receive-pack to segfault.
It's not an overflow on writing the buffer, though; the nonsense size is
passed into a FLEX_ALLOC_MEM(). In my test case, I ended up allocating a
1.4GB buffer (which just happened to be the mod-2^32 residue of my "eoc"
pointer), and the segfault comes from trying to read an unallocated
page.

So I don't think it's exploitable in any interesting way.

> diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c
> index feafb076a4..116f3177a1 100644
> --- a/builtin/receive-pack.c
> +++ b/builtin/receive-pack.c
> @@ -1524,7 +1524,7 @@ static void queue_commands_from_cert(struct command **tail,
>  
>  	while (boc < eoc) {
>  		const char *eol = memchr(boc, '\n', eoc - boc);
> -		tail = queue_command(tail, boc, eol ? eol - boc : eoc - eol);
> +		tail = queue_command(tail, boc, eol ? eol - boc : eoc - boc);
>  		boc = eol ? eol + 1 : eoc;
>  	}
>  }

The patch itself is obviously an improvement. It may be worth graduating
separately from the rest of the series.

-Peff

  reply	other threads:[~2017-03-28  6:51 UTC|newest]

Thread overview: 40+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-03-26 16:01 [PATCH v2 00/21] object_id part 7 brian m. carlson
2017-03-26 16:01 ` [PATCH v2 01/21] Define new hash-size constants for allocating memory brian m. carlson
2017-03-26 16:01 ` [PATCH v2 02/21] Convert GIT_SHA1_HEXSZ used for allocation to GIT_MAX_HEXSZ brian m. carlson
2017-03-26 16:01 ` [PATCH v2 03/21] Convert GIT_SHA1_RAWSZ used for allocation to GIT_MAX_RAWSZ brian m. carlson
2017-03-26 16:01 ` [PATCH v2 04/21] builtin/diff: convert to struct object_id brian m. carlson
2017-03-26 16:01 ` [PATCH v2 05/21] builtin/pull: convert portions " brian m. carlson
2017-03-26 16:01 ` [PATCH v2 06/21] builtin/receive-pack: fix incorrect pointer arithmetic brian m. carlson
2017-03-28  6:51   ` Jeff King [this message]
2017-03-28 16:58     ` Junio C Hamano
2017-03-26 16:01 ` [PATCH v2 07/21] builtin/receive-pack: convert portions to struct object_id brian m. carlson
2017-03-28  7:07   ` Jeff King
2017-03-29 23:21     ` brian m. carlson
2017-03-30  1:37       ` Jeff King
2017-03-26 16:01 ` [PATCH v2 08/21] fsck: convert init_skiplist " brian m. carlson
2017-03-26 16:01 ` [PATCH v2 09/21] parse-options-cb: convert sha1_array_append caller " brian m. carlson
2017-03-26 16:01 ` [PATCH v2 10/21] test-sha1-array: convert most code " brian m. carlson
2017-03-26 16:01 ` [PATCH v2 11/21] sha1_name: convert struct disambiguate_state to object_id brian m. carlson
2017-03-26 16:01 ` [PATCH v2 12/21] sha1_name: convert disambiguate_hint_fn to take object_id brian m. carlson
2017-03-26 16:01 ` [PATCH v2 13/21] submodule: convert check_for_new_submodule_commits to object_id brian m. carlson
2017-03-26 16:01 ` [PATCH v2 14/21] builtin/pull: convert to struct object_id brian m. carlson
2017-03-26 16:01 ` [PATCH v2 15/21] sha1-array: convert internal storage for struct sha1_array to object_id brian m. carlson
2017-03-28  7:24   ` Jeff King
2017-03-26 16:01 ` [PATCH v2 16/21] Make sha1_array_append take a struct object_id * brian m. carlson
2017-03-28  7:26   ` Jeff King
2017-03-28 17:27   ` Junio C Hamano
2017-03-29  0:06     ` brian m. carlson
2017-03-29 15:14       ` Junio C Hamano
2017-03-29 22:28         ` brian m. carlson
2017-03-26 16:01 ` [PATCH v2 17/21] Convert remaining callers of sha1_array_lookup to object_id brian m. carlson
2017-03-26 16:01 ` [PATCH v2 18/21] Convert sha1_array_lookup to take struct object_id brian m. carlson
2017-03-26 16:01 ` [PATCH v2 19/21] Convert sha1_array_for_each_unique and for_each_abbrev to object_id brian m. carlson
2017-03-26 16:01 ` [PATCH v2 20/21] Rename sha1_array to oid_array brian m. carlson
2017-03-26 16:01 ` [PATCH v2 21/21] Documentation: update and rename api-sha1-array.txt brian m. carlson
2017-03-28  7:31 ` [PATCH v2 00/21] object_id part 7 Jeff King
2017-03-28 11:13   ` brian m. carlson
2017-03-28 17:35     ` Jeff King
2017-03-28 17:42       ` Jeff King
2017-03-28 19:40         ` Junio C Hamano
2017-03-28 20:00           ` Jeff King
2017-03-28 17:32   ` Junio C Hamano

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=20170328065123.f4uswxxznv3wyqaz@sigill.intra.peff.net \
    --to=peff@peff.net \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=pclouds@gmail.com \
    --cc=sandals@crustytoothpaste.net \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.