NULL pointer dereference in `git_worktree_lookup` on a repository without a git directory
维护者通常 1 天内回复
还没有人认领这个 Issue。
评估
- 难度
- 2/5
- 预计耗时
- 1-3 小时
- 新手友好度
- 78/100
- Issue 类型
- 缺陷
- 描述清晰度
- 描述清楚
- 活跃度
- 活跃
- 技术栈
- c, git
调研方向
阅读 src/libgit2/worktree.c 中的 git_worktree_lookup,并比较 git_worktree_list() 如何处理没有公共目录的仓库。首先检查现有的 worktree 测试,查找用于设置仓库的辅助函数,然后添加一个仅使用对象数据库的回归测试用例。完成标准是查找返回 GIT_ENOTFOUND 且不会崩溃。
由索引模型根据 Issue 内容生成。
描述
First of all, thank you so much for maintaining libgit2; while applying our testing tool across multiple Rust crates during its evaluation, we encountered an issue in libgit2 (reached through the Rust binding git2) that I would like to bring to your attention.
git_worktree_lookup() passes a NULL repo->commondir to strlen when the repository has no git directory, for example one created with git_repository_wrap_odb().
I notice the following code may have a problem: https://github.com/libgit2/libgit2/blob/42a89d7cc9374a19e72fa57011e5fe3a99c7b3bf/src/libgit2/worktree.c#L189
Describe the bug
int git_worktree_lookup(git_worktree **out, git_repository *repo, const char *name)
{
...
GIT_ASSERT_ARG(repo);
GIT_ASSERT_ARG(name);
*out = NULL;
if ((error = git_str_join3(&path, '/', repo->commondir, "worktrees", name)) < 0)
goto out;
A repository made by git_repository_wrap_odb() has no git directory, so repo->commondir is NULL. git_str_join3() calls strlen() on each of its three strings (src/util/str.c#L816) and reads from address 0.
git_worktree_list() uses git_str_joinpath() on the same field instead, which accepts NULL, so it does not crash in this case.
Tested on libgit2 1.9.7, the latest release (as bundled by libgit2-sys 0.18.8+1.9.7, used by git2 0.21.0). Current main (42a89d7) has the same code.
To Reproduce
- Create a repository without a git directory with
git_odb_new+git_repository_wrap_odb. - Call
git_worktree_lookup(&wt, repo, "a").
Through the safe Rust binding git2 0.21.0:
fn main() {
// a repository with an object database only, no git directory
let repo = git2::Repository::from_odb(git2::Odb::new().unwrap()).unwrap();
let _ = repo.find_worktree("a");
}
Expected behavior
The lookup should return "not found" (GIT_ENOTFOUND), since such a repository has no worktrees, not crash the process.
output (AddressSanitizer, libgit2 built with -fsanitize=address):
==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000
==The signal is caused by a READ memory access.
#1 strlen
#2 git_str_join3
#3 git_worktree_lookup
#4 git2::repo::Repository::find_worktree
Without AddressSanitizer the process is killed by SIGSEGV.
Suggested fix
Return "not found" when there is no common directory (src/libgit2/worktree.c, git_worktree_lookup):
*out = NULL;
/* a repository without a git directory (git_repository_wrap_odb) has no worktrees */
if (repo->commondir == NULL) {
git_error_set(GIT_ERROR_WORKTREE, "worktree '%s' not found", name);
return GIT_ENOTFOUND;
}
if ((error = git_str_join3(&path, '/', repo->commondir, "worktrees", name)) < 0)
goto out;
I applied this to the libgit2 1.9.7 sources bundled in libgit2-sys. The reproducer then gets GIT_ENOTFOUND (worktree 'a' not found) with no crash.
Thank you for your time.
- 主要语言
- C
- 星标
- 10.6k
- 派生
- 2.7k
- 平均合并
- 1 天 5 小时
- 30 天内合并 PR
- 5
环境准备
在浏览器里用你自己的 GitHub 账号启动这个项目的开发容器。
- 没有 Dockerfile 或 Docker Compose 文件
- 没有 Pull Request 模板
- 阅读贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
libgit2/libgit2 的其他 Issue
-
NULL pointer dereference in `git_submodule_add_setup` on a repository without a working directory未关闭
难度 2/5 1-3 小时 新手友好度 84/100
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 84/100
维护者通常 1 天内回复
-
难度 1/5 1 小时以内 新手友好度 88/100
libgit2/libgit2#7455 · 1 条评论 ·
维护者通常 1 天内回复
-
SecureTransport proxy error cleanup frees borrowed stream before TLS close可能重新可做 @Tiancheng-Xu 于 19 天前认领,目前没有进行中的 PR。 未关闭
难度 2/5 1-3 小时 新手友好度 78/100
libgit2/libgit2#7432 · 1 条评论 ·
维护者通常 1 天内回复
-
[BUG] Uninitialized `db` freed in `git_refdb_open` on allocation failure可能已有人在做 @cristianchiriac 于 21 天前认领。 未关闭
难度 2/5 1-3 小时 新手友好度 72/100
维护者通常 1 天内回复
相似的 Issue
-
XPM values line with more than one space between numbers raises ValueError可能已有人在做 关联的 PR 仍在进行中或已合并。 未关闭
难度 2/5 1-3 小时 新手友好度 86/100
python-pillow/Pillow#10429 ·
维护者通常 1 天内回复
-
bug
难度 2/5 1-3 小时 新手友好度 83/100
维护者通常 1 天内回复
-
难度 1/5 1 小时以内 新手友好度 85/100
维护者通常 9 天内回复
-
难度 2/5 1-3 小时 新手友好度 72/100
containers/bubblewrap#826 ·
维护者通常 1 天内回复
-
难度 1/5 1-3 小时 新手友好度 62/100
Revivedx/SavageWindRecomp#488 ·
维护者通常 1 天内回复