diff --git a/docs/usage.md b/docs/usage.md index 53f70445..ddae3ba5 100644 --- a/docs/usage.md +++ b/docs/usage.md @@ -622,6 +622,9 @@ would be required when not using `setuptools-scm`. - ✅ **Check**: Is setuptools-scm installed in your build environment? - ✅ **Check**: Are you in a valid SCM repository? +**Problem: Error about dubious ownership** +- CVE-2022-24765 identified security issues with git trusting repositories owned by another user. If the file-finder detects that git is unable to list files because it is operating in a git directory owned by another user, it will raise an error. Since this was not the default behaviour of `setuptools_scm` previously, you can override this by setting `SETUPTOOLS_SCM_IGNORE_DUBIOUS_OWNER`, but be warned git will not be listing files correctly with this flag set. + ### Timestamps for Local Development Versions !!! info "Improved Timestamp Behavior" diff --git a/src/setuptools_scm/_file_finders/git.py b/src/setuptools_scm/_file_finders/git.py index 4379c21a..02589898 100644 --- a/src/setuptools_scm/_file_finders/git.py +++ b/src/setuptools_scm/_file_finders/git.py @@ -22,6 +22,18 @@ def _git_toplevel(path: str) -> str | None: cwd = os.path.abspath(path or ".") res = _run(["git", "rev-parse", "HEAD"], cwd=cwd) if res.returncode: + # This catches you being in a git directory, but the + # permissions being incorrect. With modern contanizered + # CI environments you can easily end up in a cloned repo + # with incorrect permissions and we don't want to silently + # ignore files. + if "--add safe.directory" in res.stderr and not os.environ.get( + "SETUPTOOLS_SCM_IGNORE_DUBIOUS_OWNER" + ): + log.error(res.stderr) + raise SystemExit( + "git introspection failed: {}".format(res.stderr.split("\n")[0]) + ) # BAIL if there is no commit log.error("listing git files failed - pretending there aren't any") return None diff --git a/testing/test_git.py b/testing/test_git.py index 31cac7a3..2377e0f3 100644 --- a/testing/test_git.py +++ b/testing/test_git.py @@ -5,6 +5,7 @@ import shutil import subprocess import sys +import textwrap from datetime import date from datetime import datetime @@ -19,6 +20,7 @@ import pytest import setuptools_scm._file_finders +import setuptools_scm._file_finders.git from setuptools_scm import Configuration from setuptools_scm import NonNormalizedVersion @@ -861,3 +863,35 @@ def test_git_no_commits_uses_fallback_version(wd: WorkDir) -> None: assert str(version_no_fallback.tag) == "0.0" assert version_no_fallback.distance == 0 assert version_no_fallback.dirty is True + + +@pytest.mark.issue("https://github.com/pypa/setuptools-scm/issues/784") +def test_dubious_dir( + wd: WorkDir, caplog: pytest.LogCaptureFixture, monkeypatch: pytest.MonkeyPatch +) -> None: + """Test that we exit clearly if we are in a unsafe directory""" + wd.commit_testfile() + git_wd = git.GitWorkdir(wd.cwd) + + def _run(*args, **kwargs) -> CompletedProcess: # type: ignore[no-untyped-def] + """Fake "git rev-parse HEAD" to fail as if you do not own the git repo""" + stderr = textwrap.dedent(f""" + fatal: detected dubious ownership in repository at '{git_wd}' + To add an exception for this directory, call: + + git config --global --add safe.directory /this/is/a/fake/path + """) + orig_run = run + if args[0] == ["git", "rev-parse", "HEAD"]: + return CompletedProcess( + args=[], stdout="%cI", stderr=stderr, returncode=128 + ) + return orig_run(*args, **kwargs) + + monkeypatch.setattr(setuptools_scm._file_finders.git, "_run", _run) + with pytest.raises(SystemExit): + git_find_files(str(wd.cwd)) + + assert "fatal: detected dubious ownership in repository" in " ".join( + caplog.messages + )