From: Jonathan Nieder <jrnieder@gmail.com>
To: Jeff King <peff@peff.net>
Cc: demerphq <demerphq@gmail.com>, Git <git@vger.kernel.org>,
"Ævar Arnfjörð Bjarmason" <avarab@gmail.com>
Subject: Re: [PATCH v2] config: avoid "write_in_full(fd, buf, len) < len" pattern
Date: Wed, 13 Sep 2017 12:49:17 -0700 [thread overview]
Message-ID: <20170913194917.GI27425@aiede.mtv.corp.google.com> (raw)
In-Reply-To: <20170913185848.5ht44spbakzkrsu6@sigill.intra.peff.net>
Jeff King wrote:
> AFAIK there's no way to turn it on for specific functions, but I'm far
> from a gcc-warning guru. Even if you could, though, the error may be far
> from the function (e.g., if we store the result in an ssize_t and then
> compare that with a size_t).
It turns out that yes, we have two of those. Both handle errors
separately already, so they should be safe.
While investigating the second, I noticed that read_in_full can
overflow its return value. malloc doesn't typically allow allocating
a buffer with size greater than SSIZE_MAX so this should be safe, but
it would be confusing to static analyzers.
Combining these observations yields the following (just for
illustration):
diff --git i/bulk-checkin.c w/bulk-checkin.c
index 9a1f6c49ab..f8e3060041 100644
--- i/bulk-checkin.c
+++ w/bulk-checkin.c
@@ -114,7 +114,7 @@ static int stream_to_pack(struct bulk_checkin_state *state,
unsigned char ibuf[16384];
if (size && !s.avail_in) {
- ssize_t rsize = size < sizeof(ibuf) ? size : sizeof(ibuf);
+ size_t rsize = size < sizeof(ibuf) ? size : sizeof(ibuf);
if (read_in_full(fd, ibuf, rsize) != rsize)
die("failed to read %d bytes from '%s'",
(int)rsize, path);
diff --git i/combine-diff.c w/combine-diff.c
index 9e163d5ada..e966d4f393 100644
--- i/combine-diff.c
+++ w/combine-diff.c
@@ -1026,7 +1026,7 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
result_size = fill_textconv(textconv, df, &result);
free_filespec(df);
} else if (0 <= (fd = open(elem->path, O_RDONLY))) {
- size_t len = xsize_t(st.st_size);
+ ssize_t len = xssize_t(st.st_size);
ssize_t done;
int is_file, i;
@@ -1040,6 +1040,8 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent,
if (!is_file)
elem->mode = canon_mode(S_IFLNK);
+ if (len > ULONG_MAX)
+ die("cannot handle files this big");
result_size = len;
result = xmallocz(len);
diff --git i/git-compat-util.h w/git-compat-util.h
index 6678b488cc..20fea81589 100644
--- i/git-compat-util.h
+++ w/git-compat-util.h
@@ -903,6 +903,13 @@ static inline size_t xsize_t(off_t len)
return (size_t)len;
}
+static inline ssize_t xssize_t(off_t len)
+{
+ if (len > SSIZE_MAX)
+ die("cannot handle files this big");
+ return (ssize_t)len;
+}
+
__attribute__((format (printf, 3, 4)))
extern int xsnprintf(char *dst, size_t max, const char *fmt, ...);
diff --git i/wrapper.c w/wrapper.c
index 36630e5d18..2b52b7367d 100644
--- i/wrapper.c
+++ w/wrapper.c
@@ -314,6 +314,9 @@ ssize_t read_in_full(int fd, void *buf, size_t count)
char *p = buf;
ssize_t total = 0;
+ if (count > SSIZE_MAX)
+ BUG("read_in_full called with absurdly high count %"PRIuMAX,
+ (uintmax_t) count);
while (count > 0) {
ssize_t loaded = xread(fd, p, count);
if (loaded < 0)
next prev parent reply other threads:[~2017-09-13 19:49 UTC|newest]
Thread overview: 46+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-09-13 11:59 Bug: git branch --unset-upstream command can nuke config when disk is full demerphq
2017-09-13 12:34 ` Jeff King
2017-09-13 13:38 ` demerphq
2017-09-13 14:17 ` Jeff King
2017-09-13 14:49 ` demerphq
2017-09-13 14:51 ` Jeff King
2017-09-13 15:18 ` demerphq
2017-09-13 15:22 ` Jeff King
2017-09-13 15:49 ` demerphq
2017-09-13 17:08 ` [PATCH 0/7] config.c may fail to notice some write() failures Jeff King
2017-09-13 17:11 ` [PATCH 1/7] config: avoid "write_in_full(fd, buf, len) < len" pattern Jeff King
2017-09-13 17:47 ` Jonathan Nieder
2017-09-13 17:53 ` Jeff King
2017-09-13 17:59 ` Jonathan Nieder
2017-09-13 18:11 ` Jeff King
2017-09-13 18:15 ` [PATCH v2] " Jeff King
2017-09-13 18:24 ` Jonathan Nieder
2017-09-13 18:58 ` Jeff King
2017-09-13 19:18 ` Jonathan Nieder
2017-09-13 19:49 ` Jonathan Nieder [this message]
2017-09-13 22:43 ` Ramsay Jones
2017-09-13 23:31 ` Ramsay Jones
2017-09-15 0:37 ` Jeff King
2017-09-15 15:15 ` Ramsay Jones
2017-09-13 21:33 ` Junio C Hamano
2017-09-13 17:11 ` [PATCH 2/7] get-tar-commit-id: check write_in_full() return against 0 Jeff King
2017-09-13 17:53 ` Jonathan Nieder
2017-09-13 18:02 ` Jeff King
2017-09-13 18:37 ` Jeff King
2017-09-13 21:09 ` Jonathan Nieder
2017-09-15 0:40 ` Jeff King
2017-09-13 17:16 ` [PATCH 3/7] avoid "write_in_full(fd, buf, len) != len" pattern Jeff King
2017-09-13 21:14 ` Jonathan Nieder
2017-09-15 0:42 ` Jeff King
2017-09-13 17:16 ` [PATCH 4/7] convert less-trivial versions of "write_in_full() != len" Jeff King
2017-09-13 21:16 ` Jonathan Nieder
2017-09-13 17:17 ` [PATCH 5/7] pkt-line: check write_in_full() errors against "< 0" Jeff King
2017-09-13 21:17 ` Jonathan Nieder
2017-09-13 17:17 ` [PATCH 6/7] notes-merge: use ssize_t for write_in_full() return value Jeff King
2017-09-13 21:20 ` Jonathan Nieder
2017-09-15 0:43 ` Jeff King
2017-09-13 17:17 ` [PATCH 7/7] config: flip return value of store_write_*() Jeff King
2017-09-13 21:25 ` Jonathan Nieder
2017-09-15 0:46 ` Jeff King
2017-09-13 18:47 ` [PATCH 8/7] read_pack_header: handle signed/unsigned comparison in read result Jeff King
2017-09-13 19:11 ` Jonathan Nieder
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
List information: http://vger.kernel.org/majordomo-info.html
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20170913194917.GI27425@aiede.mtv.corp.google.com \
--to=jrnieder@gmail.com \
--cc=avarab@gmail.com \
--cc=demerphq@gmail.com \
--cc=git@vger.kernel.org \
--cc=peff@peff.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.
Code repositories for project(s) associated with this public inbox
https://80x24.org/mirrors/git.git
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 read-only IMAP folder(s) and NNTP newsgroup(s).