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

[PATCH] strbuf: support long paths w/o read rights in strbuf_getcwd() on FreeBSD

From
René Scharfe <l.s.r@web.de>
Date
Mar 26, 2017, 13:43 UTC
Message-ID
<4026bc3b-2999-9daf-d6ab-10c6d007b1e7@web.de>

FreeBSD implements getcwd(3) as a syscall, but falls back to a version based on readdir(3) if it fails for some reason. The latter requires permissions to read and execute path components, while the former does not. That means that if our buffer is too small and we're missing rights we could get EACCES, but we may succeed with a bigger buffer.

Keep retrying if getcwd(3) indicates lack of permissions until our buffer can fit PATH_MAX bytes, as that's the maximum supported by the syscall on FreeBSD anyway. This way we do what we can to be able to benefit from the syscall, but we also won't loop forever if there is a real permission issue.

This fixes a regression introduced with 7333ed17 (setup: convert setup_git_directory_gently_1 et al. to strbuf, 2014-07-28) for paths longer than 127 bytes with components that miss read or execute permissions (e.g. 0711 on /home for privacy reasons); we used a fixed PATH_MAX-sized buffer before.

Reported-by: Zenobiusz Kunegunda <zenobiusz.kunegunda@interia.pl>
Signed-off-by: Rene Scharfe <l.s.r@web.de>
---
 strbuf.c        | 11 +++++++++++
 t/t0001-init.sh | 14 ++++++++++++++
 2 files changed, 25 insertions(+)
diff --git a/strbuf.c b/strbuf.c
index ace58e7367..00457940cf 100644
--- a/strbuf.c
+++ b/strbuf.c
@@ -449,6 +449,17 @@ int strbuf_getcwd(struct strbuf *sb)
 			strbuf_setlen(sb, strlen(sb->buf));
 			return 0;
 		}
+
+		/*
+		 * If getcwd(3) is implemented as a syscall that falls
+		 * back to a regular lookup using readdir(3) etc. then
+		 * we may be able to avoid EACCES by providing enough
+		 * space to the syscall as it's not necessarily bound
+		 * to the same restrictions as the fallback.
+		 */
+		if (errno == EACCES && guessed_len < PATH_MAX)
+			continue;
+
 		if (errno != ERANGE)
 			break;
 	}
diff --git a/t/t0001-init.sh b/t/t0001-init.sh
index e424de5363..5f81fbe07c 100755
--- a/t/t0001-init.sh
+++ b/t/t0001-init.sh
@@ -315,6 +315,20 @@ test_expect_success 'init with separate gitdir' '
 	test_path_is_dir realgitdir/refs
 '
 
+test_expect_success 'init in long base path' '
+	# exceed initial buffer size of strbuf_getcwd()
+	component=123456789abcdef &&
+	test_when_finished "chmod 0700 $component; rm -rf $component" &&
+	p31=$component/$component &&
+	p127=$p31/$p31/$p31/$p31 &&
+	mkdir -p $p127 &&
+	chmod 0111 $component &&
+	(
+		cd $p127 &&
+		git init newdir
+	)
+'
+
 test_expect_success 're-init on .git file' '
 	( cd newdir && git init )
 '
-- 
2.12.2
Next: Junio C Hamano
Message 1 of 10 in “strbuf: support long paths w/o read rights in strbuf_getcwd() on FreeBSD”
  1. strbuf: support long paths w/o read rights in strbuf_getcwd() on FreeBSDRené Scharfe, Mar 26, 2017
  2. Junio C HamanoMar 27, 2017
  3. Zenobiusz KunegundaMar 27, 2017
  4. Junio C HamanoMar 27, 2017
  5. Christian CouderMar 28, 2017
  6. Stefan BellerMar 28, 2017
  7. Christian CouderMar 28, 2017
  8. Jeff KingMar 28, 2017
  9. Christian CouderMar 29, 2017
  10. René ScharfeMar 30, 2017

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.