Skip to content

Fix user git access#4253

Open
rasapala wants to merge 21 commits into
mainfrom
CVS-187604_user_download
Open

Fix user git access#4253
rasapala wants to merge 21 commits into
mainfrom
CVS-187604_user_download

Conversation

@rasapala

@rasapala rasapala commented May 28, 2026

Copy link
Copy Markdown
Collaborator

🛠 Summary

JIRA CVS-187604
Disables libgit2 owner validation for repositories opened by OVMS.
Clears selected libgit2 git config search paths to avoid reading host/user git configuration.
Disables pack .keep file checks to reduce stat calls during repository operations.

🧪 Checklist

  • Unit tests added.
  • The documentation updated.
  • Change follows security best practices.
    ``

Copilot AI review requested due to automatic review settings May 28, 2026 09:18

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR updates libgit2 initialization for Hugging Face git-clone based model pulls to avoid repository access failures when model directories are owned by a different OS user.

Changes:

  • Disables libgit2 owner validation for repositories opened by OVMS.
  • Clears selected libgit2 git config search paths to avoid reading host/user git configuration.
  • Disables pack .keep file checks to reduce stat calls during repository operations.

Comment thread src/pull_module/libgit2.cpp Outdated
Comment thread src/pull_module/libgit2.cpp Outdated
@rasapala rasapala requested review from dtrawins and mzegla May 28, 2026 12:03
@rasapala rasapala requested a review from atobiszei June 8, 2026 08:45
Comment thread src/pull_module/libgit2.cpp Outdated
Comment on lines +263 to +275
// Redirect all git config search paths to an empty string so libgit2 never reads
// host-level git configuration (~/.gitconfig, /etc/gitconfig, etc.). Without this,
// a host gitconfig that sets credential.helper, http.proxy, lfs.*, or safe.directory
// can silently override OVMS's intended proxy/token settings and cause spurious
// failures or credential leaks in multi-tenant environments.
// On Windows, GIT_CONFIG_LEVEL_PROGRAMDATA covers %PROGRAMDATA%\Git\config which is
// a machine-wide config that libgit2 reads before SYSTEM; it must be cleared as well.
this->status = git_libgit2_opts(GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_SYSTEM, "");
IF_ERROR_SET_MSG_AND_RETURN();
this->status = git_libgit2_opts(GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_XDG, "");
IF_ERROR_SET_MSG_AND_RETURN();
this->status = git_libgit2_opts(GIT_OPT_SET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, "");
IF_ERROR_SET_MSG_AND_RETURN();

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't this be limited only to container environments? Even then(in container) one could want to override some git settings used by OVMS.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The settings may affect the resume and download logic. We do not want to risk this kind of situation.

Comment thread src/pull_module/libgit2.cpp Outdated
candidates.hasWipMarker = libgit2::hasLfsWipMarker(downloadPath);
candidates.hasLfsErrorFile = libgit2::hasLfsErrorFile(downloadPath);

ResumeCandidates buildResumeCandidates(git_repository* repo, const std::string& downloadPath, ResumeCandidates candidates) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor but we create a copy of resume candidates. Couldn't we return ptr then?

Comment thread src/pull_module/libgit2.cpp Outdated
// The user has copied model files in by hand; skip the pull and let model loading proceed
// against whatever files are already on disk. Use --overwrite_models to replace it with a
// fresh download.
bool resumeCheckSecondCondition(const std::string& downloadPath, const ResumeCandidates& candidates) {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

First/Second -> whats the meaning of First/Second? Be more descriptive in naming. eg resumeCheckDotGitExistence

Comment thread src/pull_module/libgit2.cpp Outdated
return StatusCode::OK;
}

Status handleExistingRepositoryWithoutOverwrite(const std::string& downloadPath,

@atobiszei atobiszei Jun 8, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the context of:

Image It could just be to resumeClone? Or maybe resumeCloneIfNotLocal?handleExistingRepository

overwrite is confusing at this point

Comment thread src/pull_module/libgit2.cpp Outdated
}

auto candidates = buildResumeCandidates(repoGuard.get(), downloadPath);
candidates = buildResumeCandidates(repoGuard.get(), downloadPath, std::move(candidates));

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just pass candidates as reference?

Comment thread src/test/libgit2_test.cpp Outdated

class Libgt2InitGuardTest : public ::testing::Test {
protected:
TempDir td;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not used?

Comment thread src/pull_module/libgit2.cpp Outdated
// container vs. a non-root serving user).
this->status = git_libgit2_opts(GIT_OPT_SET_OWNER_VALIDATION, 0);
IF_ERROR_SET_MSG_AND_RETURN();
const char* enableSearchPathEnv = std::getenv("GIT_OPT_SET_ENABLE_SEARCH_PATHS");

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use ovms::GetEnvVar

Comment thread src/pull_module/libgit2.cpp
Comment thread src/test/libgit2_test.cpp Outdated
Comment on lines +914 to +953
envGuard.set("GIT_OPT_SET_ENABLE_SEARCH_PATHS", "1");

std::array<std::string, 3> baselinePaths;
ASSERT_EQ(git_libgit2_init(), 1);
{
git_buf systemBuf = GIT_BUF_INIT;
ASSERT_EQ(git_libgit2_opts(GIT_OPT_GET_SEARCH_PATH, GIT_CONFIG_LEVEL_SYSTEM, &systemBuf), 0);
baselinePaths[0] = (systemBuf.ptr != nullptr) ? systemBuf.ptr : "";
git_buf_dispose(&systemBuf);

git_buf xdgBuf = GIT_BUF_INIT;
ASSERT_EQ(git_libgit2_opts(GIT_OPT_GET_SEARCH_PATH, GIT_CONFIG_LEVEL_XDG, &xdgBuf), 0);
baselinePaths[1] = (xdgBuf.ptr != nullptr) ? xdgBuf.ptr : "";
git_buf_dispose(&xdgBuf);

git_buf globalBuf = GIT_BUF_INIT;
ASSERT_EQ(git_libgit2_opts(GIT_OPT_GET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, &globalBuf), 0);
baselinePaths[2] = (globalBuf.ptr != nullptr) ? globalBuf.ptr : "";
git_buf_dispose(&globalBuf);
}
git_libgit2_shutdown();

ovms::Libgt2InitGuard guard(defaultOpts);
ASSERT_GE(guard.status, 0);

git_buf systemBuf = GIT_BUF_INIT;
ASSERT_EQ(git_libgit2_opts(GIT_OPT_GET_SEARCH_PATH, GIT_CONFIG_LEVEL_SYSTEM, &systemBuf), 0);
EXPECT_EQ((systemBuf.ptr != nullptr) ? systemBuf.ptr : "", baselinePaths[0]);
git_buf_dispose(&systemBuf);

git_buf xdgBuf = GIT_BUF_INIT;
ASSERT_EQ(git_libgit2_opts(GIT_OPT_GET_SEARCH_PATH, GIT_CONFIG_LEVEL_XDG, &xdgBuf), 0);
EXPECT_EQ((xdgBuf.ptr != nullptr) ? xdgBuf.ptr : "", baselinePaths[1]);
git_buf_dispose(&xdgBuf);

git_buf globalBuf = GIT_BUF_INIT;
ASSERT_EQ(git_libgit2_opts(GIT_OPT_GET_SEARCH_PATH, GIT_CONFIG_LEVEL_GLOBAL, &globalBuf), 0);
EXPECT_EQ((globalBuf.ptr != nullptr) ? globalBuf.ptr : "", baselinePaths[2]);
git_buf_dispose(&globalBuf);
}

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Create utility that will check expected variable values with boolean parameter (useGlobal)
Then we need either 1 test or 3 tests when we check
checkifUsingGlobalConfig( boolean expectToUseGlobal)

3 cases:

  1. Undefined env GIT_OPT_SET_ENABLE_SEARCH_PATHS
  2. defined set to 0
  3. defined set to 1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants