git/list[1] front-page[2] threads[3] people[4] search[5] about
 

write() _will_ fail on Mac OS X/XNU if nbytes > INT_MAX

From
Filipe Cabecinhas <filcab@gmail.com>
Date
Apr 9, 2013, 22:31 UTC
Message-ID
<CAEDE852zw9EhmnVaWb_oa_BX_d_--TZoTcs1kgkMPHooM_E6Cw@mail.gmail.com>
Hi all,

While “git svn fetch”ing a subversion repository (private, sorry), I've encoutered a bug that appears in several git versions (always with the same symptoms):

git from master (from 2013-04-08) git version 1.8.2.1 (compiled from homebrew) git version 1.7.12.4 (Apple Git-37)

The only symptom is git blowing up with the error: fatal: write error: Invalid argument

Problems showed up when this happened (in the SVN repo): rev A: File F with 110K is replaced with a 9G file (don't ask…) intermediate revs: files got added and changed, not touching file F rev B: File F finally got reverted to the state before rev A

I can git svn fetch up to rev B-1, but svn fetching rev B will throw the previously mentioned error.

I traced it down to write() returning <0 and setting errno to EINVAL if nbytes > INT_MAX: http://fxr.watson.org/fxr/source/bsd/kern/sys_generic.c?v=xnu-2050.18.24#L573 (the write() will eventually call dofilewrite, which has that check).

Testing with dd bs=INT_MAX+1 count=1 also gets me an “Invalid argument” error, while bs=INT_MAX will do what's expected.

I have a preliminary patch that fixes it, but it may not be the preferred way. The code is not ifdef'ed out and I'm doing the fix in write_in_full(), while it may be preferred to do the fix in xwrite().

A radar bug has been submitted to Apple about this, but I think git could tolerate the bug while it isn't fixed, by working around it.

Thank you,
  Filipe
diff --git a/wrapper.c b/wrapper.c
index bac59d2..474d760 100644
--- a/wrapper.c
+++ b/wrapper.c
@@ -187,7 +187,12 @@ ssize_t write_in_full(int fd, const void *buf, size_t count)
 	ssize_t total = 0;
 
 	while (count > 0) {
-		ssize_t written = xwrite(fd, p, count);
+		ssize_t written = 0;
+        if (count >= INT_MAX)
+			written = xwrite(fd, p, INT_MAX-1);
+        else
+			written = xwrite(fd, p, count);
+
 		if (written < 0)
 			return -1;
 		if (!written) {
Next: Junio C Hamano
Message 1 of 12 in “write() _will_ fail on Mac OS X/XNU if nbytes > INT_MAX”
  1. Filipe CabecinhasApr 9, 2013
  2. Junio C HamanoApr 9, 2013
  3. Filipe CabecinhasMay 9, 2013
  4. Junio C HamanoMay 10, 2013
  5. Filipe CabecinhasMay 10, 2013
  6. Junio C HamanoMay 10, 2013
  7. Junio C HamanoMay 10, 2013
  8. Filipe CabecinhasMay 10, 2013
  9. Filipe CabecinhasMay 10, 2013
  10. Junio C HamanoMay 10, 2013
  11. Erik Faye-LundNov 20, 2013
  12. Torsten BögershausenNov 20, 2013

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.