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 <kevin@kevinlocke.name> Reviewed-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Kevin Locke committed May 24, 2022 at 13:20 UTC c37c6dc6a79a1ca7b9d4fa4efd788d8f5ec6369a
1 file changed +10 -1
setup.c
+10 -1
@@ -459,7 +459,16 @@ static void setup_original_cwd(void)
459 */
460
461 /* Normalize the directory */
462 - strbuf_realpath(&tmp, tmp_original_cwd, 1);
462 + if (!strbuf_realpath(&tmp, tmp_original_cwd, 0)) {
463 + trace2_data_string("setup", the_repository,
464 + "realpath-path", tmp_original_cwd);
465 + trace2_data_string("setup", the_repository,
466 + "realpath-failure", strerror(errno));
467 + free((char*)tmp_original_cwd);
468 + tmp_original_cwd = NULL;
469 + return;
470 + }
471 +
472 free((char*)tmp_original_cwd);
473 tmp_original_cwd = NULL;
474 startup_info->original_cwd = strbuf_detach(&tmp, NULL);