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

Re: [PATCH] setup: avoid unconditional open with write flags

From
René Scharfe <l.s.r@web.de>
Date
Dec 6, 2022, 19:47 UTC
Message-ID
<f49b915e-46d1-7e53-ae4f-b01c2028b70d@web.de>
In-Reply-To
<20221205190019.52829-1-cgzones@googlemail.com>
Am 05.12.22 um 20:00 schrieb Christian Göttsche:
Show 46 quoted lines
> Commit 57f5d52a942 ("common-main: call sanitize_stdfds()") added the
> sanitization for standard file descriptors (stdin, stdout, stderr) to
> all binaries.  The lead to all binaries unconditionally opening
> /dev/null with the flag O_RDWR (read and write).  Most of the time the
> standard file descriptors should be set up properly and the sanitization
> ends up doing nothing.
>
> There are many non modifying git operations, like `git status` or `git
> stash list`, which might be called by a parent to gather information
> about the repository.  That parent might run under a seccomp filter to
> avoid accidental modification or unwanted command execution on memory
> corruptions.  As part of that seccomp filter open(2) and openat(2) might
> be only allowed in read-only mode (O_RDONLY), thus preventing git's
> sanitation and stopping the application.
>
> Check before opening /dev/null to populate a possible non-present
> standard file descriptor if actually any is missing.
>
> Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
> ---
> Alternatively one could add a command line argument
> (`--no-stdfd-sanitization`).
> ---
>  setup.c | 9 ++++++++-
>  1 file changed, 8 insertions(+), 1 deletion(-)
>
> diff --git a/setup.c b/setup.c
> index cefd5f6..2af7170 100644
> --- a/setup.c
> +++ b/setup.c
> @@ -1669,7 +1669,14 @@ const char *resolve_gitdir_gently(const char *suspect, int *return_error_code)
>  /* if any standard file descriptor is missing open it to /dev/null */
>  void sanitize_stdfds(void)
>  {
> -	int fd = xopen("/dev/null", O_RDWR);
> +	int fd;
> +
> +	if (fcntl(0, F_GETFD) != -1 &&
> +	    fcntl(1, F_GETFD) != -1 &&
> +	    fcntl(2, F_GETFD) != -1)
> +		return;
> +
> +	fd = xopen("/dev/null", O_RDWR);
>  	while (fd < 2)
>  		fd = xdup(fd);
>  	if (fd > 2)
If read-only access is allowed, how about this?
diff --git a/setup.c b/setup.c
index cefd5f63c4..0f52c51759 100644
--- a/setup.c
+++ b/setup.c
@@ -1669,7 +1669,12 @@ const char *resolve_gitdir_gently(const char *suspect, int *return_error_code)
 /* if any standard file descriptor is missing open it to /dev/null */
 void sanitize_stdfds(void)
 {
-	int fd = xopen("/dev/null", O_RDWR);
+	int fd = xopen("/dev/null", O_RDONLY);
+	if (fd > 0)
+		close(fd);
+	if (fd > 2)
+		return;
+	fd = xopen("/dev/null", O_WRONLY);
 	while (fd < 2)
 		fd = xdup(fd);
 	if (fd > 2)

Requires an extra open/close pair if fd 0 is already open, but no extra
syscalls if 0, 1 and 2 are all open.

Can opening /dev/null (or NUL on Windows) multiple times instead of dup'ing
cause issues?  Can we e.g. lock ourselves out?

René
Previous: Junio C HamanoNext: Junio C Hamano
Message 9 of 10 in “setup: avoid unconditional open with write flags”
  1. setup: avoid unconditional open with write flagsChristian Göttsche, Dec 5, 2022
  2. brian m. carlsonDec 5, 2022
  3. Jeff KingDec 6, 2022
  4. Christian GöttscheDec 6, 2022
  5. Taylor BlauDec 5, 2022
  6. Junio C HamanoDec 6, 2022
  7. Taylor BlauDec 6, 2022
  8. Junio C HamanoDec 6, 2022
  9. René ScharfeDec 6, 2022
  10. Junio C HamanoDec 6, 2022

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.