From c37c6dc6a79a1ca7b9d4fa4efd788d8f5ec6369a Mon Sep 17 00:00:00 2001 From: Kevin Locke Date: Tue, 24 May 2022 13:20:12 -0600 Subject: [PATCH] setup: don't die if realpath(3) fails on getcwd(3) Prior to Git 2.35.0, git could be run from an inaccessible working directory so long as the git repository specified by options and/or environment variables was accessible. For example: git init repo mkdir -p a/b cd a/b chmod u-x .. git -C "${PWD%/a/b}/repo" status If this example seems a bit contrived, consider running with the repository owner as a substitute UID (e.g. with runuser(1) or sudo(8)) without ensuring the working directory is accessible by that user. The code added by e6f8861bd4 ("setup: introduce startup_info->original_cwd") to preserve the working directory attempts to normalize the path using strbuf_realpath(). If that fails, as in the case above, it is treated as a fatal error. This commit treats strbuf_realpath() errors as non-fatal. If an error occurs, setup_original_cwd() will continue without applying removal prevention for cwd, resulting in the pre-2.35.0 behavior. The risk should be minimal, since git will not operate on a repository with inaccessible ancestors, this behavior is only known to occur when cwd is a descendant of the repository, an ancestor of cwd is inaccessible, and no ancestors of the repository are inaccessible. Signed-off-by: Kevin Locke Reviewed-by: Elijah Newren Signed-off-by: Junio C Hamano --- setup.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/setup.c b/setup.c index f818dd858c..faf5095e44 100644 --- a/setup.c +++ b/setup.c @@ -459,7 +459,16 @@ static void setup_original_cwd(void) */ /* Normalize the directory */ - strbuf_realpath(&tmp, tmp_original_cwd, 1); + if (!strbuf_realpath(&tmp, tmp_original_cwd, 0)) { + trace2_data_string("setup", the_repository, + "realpath-path", tmp_original_cwd); + trace2_data_string("setup", the_repository, + "realpath-failure", strerror(errno)); + free((char*)tmp_original_cwd); + tmp_original_cwd = NULL; + return; + } + free((char*)tmp_original_cwd); tmp_original_cwd = NULL; startup_info->original_cwd = strbuf_detach(&tmp, NULL);