pack-bitmap: fix memory leak if load_bitmap() failed

After going through the "failed" label, load_bitmap() will return -1, and its caller (either prepare_bitmap_walk() or prepare_bitmap_git()) will then call free_bitmap_index(). That function would have done: struct stored_bitmap *sb; kh_foreach_value(b->bitmaps, sb { ewah_pool_free(sb->root); free(sb); }); , but won't since load_bitmap() already called kh_destroy_oid_map() and NULL'd the "bitmaps" pointer from within its "failed" label. Thus if you got part of the way through loading bitmap entries and then failed, you would leak all of the previous entries that you were able to load successfully. The solution is to remove the error handling code in load_bitmap(), because its caller will always call free_bitmap_index() in case of an error. Signed-off-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Lidong Yan <502024330056@smail.nju.edu.cn> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Taylor Blau committed Jul 1, 2025 at 05:32 UTC 3367b6657c456788e37c335bdd3225e517d2c804
1 file changed +4 -17
pack-bitmap.c
+4 -17
@@ -630,41 +630,28 @@ static int load_bitmap(struct repository *r, struct bitmap_index *bitmap_git,
630 bitmap_git->ext_index.positions = kh_init_oid_pos();
631
632 if (load_reverse_index(r, bitmap_git))
633 - goto failed;
633 + return -1;
634
635 if (!(bitmap_git->commits = read_bitmap_1(bitmap_git)) ||
636 !(bitmap_git->trees = read_bitmap_1(bitmap_git)) ||
637 !(bitmap_git->blobs = read_bitmap_1(bitmap_git)) ||
638 !(bitmap_git->tags = read_bitmap_1(bitmap_git)))
639 - goto failed;
639 + return -1;
640
641 if (!bitmap_git->table_lookup && load_bitmap_entries_v1(bitmap_git) < 0)
642 - goto failed;
642 + return -1;
643
644 if (bitmap_git->base) {
645 if (!bitmap_is_midx(bitmap_git))
646 BUG("non-MIDX bitmap has non-NULL base bitmap index");
647 if (load_bitmap(r, bitmap_git->base, 1) < 0)
648 - goto failed;
648 + return -1;
649 }
650
651 if (!recursing)
652 load_all_type_bitmaps(bitmap_git);
653
654 return 0;
655 -
656 -failed:
657 - munmap(bitmap_git->map, bitmap_git->map_size);
658 - bitmap_git->map = NULL;
659 - bitmap_git->map_size = 0;
660 -
661 - kh_destroy_oid_map(bitmap_git->bitmaps);
662 - bitmap_git->bitmaps = NULL;
663 -
664 - kh_destroy_oid_pos(bitmap_git->ext_index.positions);
665 - bitmap_git->ext_index.positions = NULL;
666 -
667 - return -1;
655 }
656
657 static int open_pack_bitmap(struct repository *r,