Git development
 help / color / mirror / Atom feed
From: Jeff King <peff@peff.net>
To: git@vger.kernel.org
Cc: Elijah Newren <newren@gmail.com>
Subject: [PATCH 3/5] xdiff: use size_t for buffer sizes
Date: Tue, 29 Sep 2026 02:54:14 -0400	[thread overview]
Message-ID: <20260929065414.GC1697497@coredump.intra.peff.net> (raw)
In-Reply-To: <20260929064935.GA1276867@coredump.intra.peff.net>

An mmfile_t stores its size as a signed long, but the more natural type
for a buffer size is size_t. This not only limits the size of entry we
can hold, but also creates some possible integer overflow issues.

For example, read_mmfile() checks that the file size fits in a size_t
before allocating, but then assigns it to a long. Likewise,
read_mmblob() and fill_mmfile() copy sizes from other types without
checking that they fit.

On LP64 systems like Linux, this is mostly academic. You could wrap to a
negative long value, but you'd need an object that's 2^63 bytes, which
is impractical.

But on an LLP64 system like Windows, a 2^31+1-byte blob could perhaps
cause mischief. We do prevent large values from entering the xdiff code
due to MAX_XDIFF_SIZE (which is itself marked as unsigned, so we'd
convert any negative "long" back to a large unsigned value). But if you
ask for binary diffs, that negative long value could instead be
converted to a huge 64-bit size_t when passed to memcmp(), diff_delta(),
etc. So probably there are paths that can cause an out-of-bounds read,
given the right set of options, but I didn't really dig for them.

On a 32-bit system things are less clear. Because "long" and "size_t"
have the same width, any time we implicitly convert to size_t, we should
get back the original size (even if the intermediate "long" is itself
negative). Probably iterating using a long could be a problem, but most
of that happens inside xdiff, which is protected by MAX_XDIFF_SIZE
(which, again, compares in the unsigned space).

Let's just use the obvious size_t type for counting the bytes. I suspect
you could still find truncation problems on LLP64 systems due to the use
of "unsigned long" throughout the code, but that's a larger problem.
This should at least nudge us in the right direction.

Note that we have to update the printf format in emit_binary_diff_body()
to accommodate the new type. Curiously it was using "%lu", even though
the type was signed (I guess compiler printf-linting is happy enough if
just the width of the format and the type match).

Signed-off-by: Jeff King <peff@peff.net>
---
 diff.c        | 2 +-
 xdiff/xdiff.h | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/diff.c b/diff.c
index 414532d09f..b4ac17f8ef 100644
--- a/diff.c
+++ b/diff.c
@@ -3646,7 +3646,7 @@ static void emit_binary_diff_body(struct diff_options *o,
 		data = delta;
 		data_size = delta_size;
 	} else {
-		char *s = xstrfmt("%lu", two->size);
+		char *s = xstrfmt("%"PRIuMAX, (uintmax_t)two->size);
 		emit_diff_symbol(o, DIFF_SYMBOL_BINARY_DIFF_HEADER_LITERAL,
 				 s, strlen(s), 0);
 		free(s);
diff --git a/xdiff/xdiff.h b/xdiff/xdiff.h
index 334eb436f6..8fa513fc4e 100644
--- a/xdiff/xdiff.h
+++ b/xdiff/xdiff.h
@@ -70,7 +70,7 @@ extern "C" {
 
 typedef struct s_mmfile {
 	char *ptr;
-	long size;
+	size_t size;
 } mmfile_t;
 
 typedef struct s_xpparam {
-- 
2.56.0.325.g545d7e68bc


  parent reply	other threads:[~2026-09-29  6:54 UTC|newest]

Thread overview: 37+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-29  6:49 [PATCH 0/5] use size_t for xdiff mmfile_t Jeff King
2026-09-29  6:51 ` [PATCH 1/5] xdiff: clean up read_mmfile() allocations on error Jeff King
2026-09-29 18:37   ` Junio C Hamano
2026-09-29  6:52 ` [PATCH 2/5] xdiff: replace mmbuffer_t with mmfile_t Jeff King
2026-09-29 11:08   ` D. Ben Knoble
2026-09-29 18:39   ` Junio C Hamano
2026-09-30 15:32   ` Patrick Steinhardt
2026-09-30 22:46     ` Jeff King
2026-10-01 15:40       ` Junio C Hamano
2026-09-29  6:54 ` Jeff King [this message]
2026-09-29  6:54 ` [PATCH 4/5] merge-ll: use read_mmfile() to read external merge results Jeff King
2026-09-29 19:22   ` Junio C Hamano
2026-09-29 20:11     ` Jeff King
2026-09-29 20:41       ` Jeff King
2026-09-29 20:43         ` [PATCH 6/5] merge-ll: handle external driver status before reading result Jeff King
2026-09-29 20:44         ` [PATCH 7/5] merge-ll: report an error when reading external merge results fails Jeff King
2026-09-29 21:19           ` Junio C Hamano
2026-09-29 21:49             ` Jeff King
2026-09-30 18:01               ` Junio C Hamano
2026-09-30 22:41                 ` Jeff King
2026-10-01 15:37                   ` Junio C Hamano
2026-09-30 15:33   ` [PATCH 4/5] merge-ll: use read_mmfile() to read external merge results Patrick Steinhardt
2026-09-30 22:50     ` Jeff King
2026-09-29  6:55 ` [PATCH 5/5] xdiff: NUL-terminate buffers read by read_mmfile() Jeff King
2026-09-30 15:32   ` Patrick Steinhardt
2026-09-30 19:59     ` Junio C Hamano
2026-09-30 22:49     ` Jeff King
2026-09-30 23:43 ` [PATCH v2 0/7] use size_t for xdiff mmfile_t Jeff King
2026-09-30 23:44   ` [PATCH v2 1/7] xdiff: clean up read_mmfile() allocations on error Jeff King
2026-09-30 23:44   ` [PATCH v2 2/7] xdiff: replace mmbuffer_t with mmfile_t Jeff King
2026-09-30 23:44   ` [PATCH v2 3/7] xdiff: use size_t for buffer sizes Jeff King
2026-09-30 23:44   ` [PATCH v2 4/7] xdiff: NUL-terminate buffers read by read_mmfile() Jeff King
2026-10-01 13:15     ` Patrick Steinhardt
2026-09-30 23:44   ` [PATCH v2 5/7] merge-ll: use read_mmfile() to read external merge results Jeff King
2026-10-01 13:15     ` Patrick Steinhardt
2026-09-30 23:44   ` [PATCH v2 6/7] merge-ll: handle external driver status before reading result Jeff King
2026-09-30 23:44   ` [PATCH v2 7/7] merge-ll: report an error when reading external merge results fails Jeff King

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=20260929065414.GC1697497@coredump.intra.peff.net \
    --to=peff@peff.net \
    --cc=git@vger.kernel.org \
    --cc=newren@gmail.com \
    /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