Skip to content

Commit 691459d

Browse files
committed
wrapper: reject count > SSIZE_MAX in read_in_full/write_in_full
Both functions accumulate bytes transferred in a ssize_t total variable, but accept a size_t count parameter. When count exceeds SSIZE_MAX, total overflows after processing SSIZE_MAX bytes, producing a negative return value that callers interpret as an error (or worse, a small positive value after further wrapping). In practice, git never passes such large counts because file sizes and buffer allocations are bounded well below SSIZE_MAX on all target platforms. The POSIX specification for read() and write() also limits single operations to SSIZE_MAX bytes, and git's xread/xwrite wrappers further clamp to MAX_IO_SIZE. But the accumulation in the _in_full wrappers means that even with per-call clamping, total can exceed SSIZE_MAX when count does. Reject count > SSIZE_MAX upfront with EINVAL rather than silently producing wrong return values. This matches the POSIX convention where read/write return EINVAL for invalid arguments. Pointed out by Coverity. Assisted-by: Claude Opus 4.6 Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
1 parent d1004ba commit 691459d

1 file changed

Lines changed: 10 additions & 0 deletions

File tree

wrapper.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,11 @@ ssize_t read_in_full(int fd, void *buf, size_t count)
288288
char *p = buf;
289289
ssize_t total = 0;
290290

291+
if (count > SSIZE_MAX) {
292+
errno = EINVAL;
293+
return -1;
294+
}
295+
291296
while (count > 0) {
292297
ssize_t loaded = xread(fd, p, count);
293298
if (loaded < 0)
@@ -307,6 +312,11 @@ ssize_t write_in_full(int fd, const void *buf, size_t count)
307312
const char *p = buf;
308313
ssize_t total = 0;
309314

315+
if (count > SSIZE_MAX) {
316+
errno = EINVAL;
317+
return -1;
318+
}
319+
310320
while (count > 0) {
311321
ssize_t written = xwrite(fd, p, count);
312322
if (written < 0)

0 commit comments

Comments
 (0)