NULL pointer dereference in `git_worktree_lookup` on a repository without a git directory
Maintainer thường phản hồi trong vòng 1 ngày
Chưa có ai nhận issue này.
Đánh giá
- Độ khó
- 2/5
- Thời gian dự kiến
- 1-3 giờ
- Mức phù hợp với người mới
- 78/100
- Loại issue
- Lỗi
- Độ rõ ràng
- Đặc tả rõ ràng
- Mức độ hoạt động
- Sôi nổi
- Công nghệ
- c, git
- Lĩnh vực
- backend-api-design, testing-qa
Hướng nghiên cứu
Đọc src/libgit2/worktree.c tại git_worktree_lookup và so sánh cách git_worktree_list() xử lý một repository không có thư mục chung. Bắt đầu bằng cách kiểm tra các bài kiểm thử worktree hiện có để tìm các hàm trợ giúp thiết lập repository, sau đó thêm một trường hợp hồi quy chỉ sử dụng cơ sở dữ liệu đối tượng. Hoàn thành khi thao tác tra cứu trả về GIT_ENOTFOUND mà không bị crash.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
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.
- Ngôn ngữ chính
- C
- Star
- 10.6k
- Fork
- 2.7k
- Merge trung bình
- 1 ngày 5 giờ
- Pull request đã merge (30 ngày)
- 5
Chuẩn bị môi trường
Khởi chạy dev container của dự án ngay trên trình duyệt, bằng tài khoản GitHub của bạn.
- Không có Dockerfile hay tệp Docker Compose
- Không có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của libgit2/libgit2
-
NULL pointer dereference in `git_submodule_add_setup` on a repository without a working directoryĐang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 84/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 84/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 88/100
libgit2/libgit2#7455 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
SecureTransport proxy error cleanup frees borrowed stream before TLS closeCó thể làm lại được @Tiancheng-Xu đã nhận 19 ngày trước và không có pull request nào đang mở. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
libgit2/libgit2#7432 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 1 ngày
-
[BUG] Uninitialized `db` freed in `git_refdb_open` on allocation failureCó thể đã có người làm @cristianchiriac đã nhận 21 ngày trước. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 72/100
Maintainer thường phản hồi trong vòng 1 ngày
Tất cả issue của libgit2/libgit2
Issue tương tự
-
bug genc
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 66/100
Maintainer thường phản hồi trong vòng 2 ngày
-
XPM values line with more than one space between numbers raises ValueErrorCó thể đã có người làm Có pull request liên kết đang mở hoặc đã được merge. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 86/100
python-pillow/Pillow#10429 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 75/100
-
bug
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 83/100
Maintainer thường phản hồi trong vòng 1 ngày