diff mbox series

unpack-objects: Fix EACCES pushing to remote on vmhgfs

Message ID 20240703134028.876-1-vano@mail.mipt.ru (mailing list archive)
State New
Headers show
Series unpack-objects: Fix EACCES pushing to remote on vmhgfs | expand

Commit Message

Ivan Pozdeev July 3, 2024, 1:40 p.m. UTC
Creating files with 0444 mode causes EACCES opening them for writing
in some setups where the creating user does not automatically have
write access.
E.g. on a vmhgfs (VMWare shared folders) with Windows host, this causes
the file on the host to be created with the read-only attribute set
which prohibits writing for everyone.

Change the mode to 0644, explicitly signaling we want write access.

Signed-off-by: Ivan Pozdeev <vano@mail.mipt.ru>
---
 object-file.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

Comments

brian m. carlson July 3, 2024, 10:40 p.m. UTC | #1
On 2024-07-03 at 13:40:28, Ivan Pozdeev wrote:
> Creating files with 0444 mode causes EACCES opening them for writing
> in some setups where the creating user does not automatically have
> write access.
> E.g. on a vmhgfs (VMWare shared folders) with Windows host, this causes
> the file on the host to be created with the read-only attribute set
> which prohibits writing for everyone.
> 
> Change the mode to 0644, explicitly signaling we want write access.

But we don't.  We don't want people to write to these files, since
they're objects and modifying them corrupts the repository.  The 0444
mode is completely intentional here.

What you're reporting actually also occurs on some broken NFS
implementations as well.  POSIX requires that implementations accept
O_RDWR with 0444[0], and we require POSIX compliance from file systems.
The solution here is to fix this in the file system so it behaves as
POSIX requires[1], which I admit may be difficult.

In addition, I'll mention that what you're doing is likely to cause you
a bunch of pain.  A Unix system is going to store different data in the
index from a Windows system, so when you do `git status` on one system
after having done it on the other, Git is going to re-read the entire
working tree, including re-hashing it, to fix the data in the index.
That's one of the reasons we don't recommend sharing a working tree
between different OSes.

[0] From https://pubs.opengroup.org/onlinepubs/9699919799/functions/open.html:

    “The argument following the oflag argument does not affect whether the
    file is open for reading, writing, or for both.”

[1] There are a lot of instances where Git fails when the file system is
    not POSIX compliant on Unix.  Notably, I believe chmod operations fail
    under WSL for Windows partitions, so doing a `git init` under WSL on a
    Windows mount tends to fail when it writes the config since the file
    system isn't POSIX compliant.
diff mbox series

Patch

diff --git a/object-file.c b/object-file.c
index 610b1f465c..bc71106ea8 100644
--- a/object-file.c
+++ b/object-file.c
@@ -2002,7 +2002,7 @@  static int create_tmpfile(struct strbuf *tmp, const char *filename)
 	strbuf_reset(tmp);
 	strbuf_add(tmp, filename, dirlen);
 	strbuf_addstr(tmp, "tmp_obj_XXXXXX");
-	fd = git_mkstemp_mode(tmp->buf, 0444);
+	fd = git_mkstemp_mode(tmp->buf, 0644);
 	if (fd < 0 && dirlen && errno == ENOENT) {
 		/*
 		 * Make sure the directory exists; note that the contents
@@ -2019,7 +2019,7 @@  static int create_tmpfile(struct strbuf *tmp, const char *filename)
 
 		/* Try again */
 		strbuf_addstr(tmp, "/tmp_obj_XXXXXX");
-		fd = git_mkstemp_mode(tmp->buf, 0444);
+		fd = git_mkstemp_mode(tmp->buf, 0644);
 	}
 	return fd;
 }