Download raw body.
gotwebd crash
On Sat, Nov 25, 2023 at 02:22:49PM +0100, Stefan Sperling wrote: > gotwebd on got.g.o crashed and left me with a core file. > > I don't have time to look into this right now. I'm preserving the > backtrace on this list. Does anyone else have ideas? > > Program terminated with signal SIGSEGV, Segmentation fault. > #0 0x000002d5b858e16c in match_packed_object (unique_id=0x766592357050, repo=0x2d7c419e450, id_str_prefix=0x2d7ffe83fc0 "a3a0e34e98c4f91a4b8fe53e24f82833a72e40a1", > obj_type=1) at /home/stsp/src/got/gotwebd/../lib/repository.c:1780 > 1780 const char *path_packidx = pe->path; > (gdb) p pe > $1 = (struct got_pathlist_entry *) 0xdfdfdfdfdfdfdfdf > (gdb) bt > #0 0x000002d5b858e16c in match_packed_object (unique_id=0x766592357050, repo=0x2d7c419e450, id_str_prefix=0x2d7ffe83fc0 "a3a0e34e98c4f91a4b8fe53e24f82833a72e40a1", > obj_type=1) at /home/stsp/src/got/gotwebd/../lib/repository.c:1780 > #1 0x000002d5b858de2f in got_repo_match_object_id_prefix (id=0x766592357050, id_str_prefix=0x2d7ffe83fc0 "a3a0e34e98c4f91a4b8fe53e24f82833a72e40a1", obj_type=1, > repo=0x2d7c419e450) at /home/stsp/src/got/gotwebd/../lib/repository.c:1945 > #2 0x000002d5b8558e78 in got_get_repo_commits (c=0x2d807b54000, limit=1) at /home/stsp/src/got/gotwebd/got_operations.c:354 > #3 0x000002d5b8554e2a in gotweb_process_request (c=0x2d807b54000) at /home/stsp/src/got/gotwebd/gotweb.c:220 > #4 0x000002d5b8553ea3 in fcgi_parse_params (buf=0x2d807b54164 "\001\005", n=0, c=0x2d807b54000, id=1) at /home/stsp/src/got/gotwebd/fcgi.c:191 > #5 0x000002d5b8553af6 in fcgi_parse_record (buf=0x2d807b5415c "\001\004", n=16, c=0x2d807b54000) at /home/stsp/src/got/gotwebd/fcgi.c:137 > #6 0x000002d5b85537fb in fcgi_request (fd=87, events=2, arg=0x2d807b54000) at /home/stsp/src/got/gotwebd/fcgi.c:93 > #7 0x000002d7efd1b32f in event_process_active (base=0x2d8aa359800) at /usr/src/lib/libevent/event.c:333 > #8 event_base_loop (base=0x2d8aa359800, flags=<optimized out>) at /usr/src/lib/libevent/event.c:483 > #9 0x000002d5b854bf3b in sockets (env=0x2d8aa3807a0, fd=3) at /home/stsp/src/got/gotwebd/sockets.c:126 > #10 0x000002d5b854f1e3 in main (argc=0, argv=0x766592357878) at /home/stsp/src/got/gotwebd/gotwebd.c:355 > (gdb) > > It looks like the problem is a call to refresh_packidx_paths() within functions called while looping over repo->pathidx_paths: got_object_get_type() -> got_object_open() -> got_object_open_packed() -> got_repo_search_packidx() -> refresh_packidx_paths() The patch below should fix it. This is a quick fix just for this code path. Other places looping over this list don't seem to be doing anything dangerous. This could be improved upon later but I think it is good enough for now. ok? diff /home/stsp/src/got commit - 2bde3e78a5bd6619af838df19eec530e23783c0b path + /home/stsp/src/got blob - f44259d099d9b70c547d238971a7cc147c4e209f file + lib/got_lib_repository.h --- lib/got_lib_repository.h +++ lib/got_lib_repository.h @@ -66,6 +66,7 @@ struct got_repository { enum got_hash_algorithm algo; struct got_pathlist_head packidx_paths; + int no_packidx_refresh; struct timespec pack_path_mtime; /* The pack index cache speeds up search for packed objects. */ blob - b3b8dfbf8803c64c39fe81209b84b6fa8fd4d79a file + lib/repository.c --- lib/repository.c +++ lib/repository.c @@ -713,6 +713,7 @@ got_repo_open(struct got_repository **repop, const cha RB_INIT(&repo->packidx_bloom_filters); TAILQ_INIT(&repo->packidx_paths); + repo->no_packidx_refresh = 0; for (i = 0; i < nitems(repo->privsep_children); i++) { memset(&repo->privsep_children[i], 0, @@ -1299,6 +1300,9 @@ refresh_packidx_paths(struct got_repository *repo) char *objects_pack_dir = NULL; struct stat sb; + if (repo->no_packidx_refresh) + return NULL; + objects_pack_dir = got_repo_get_path_objects_pack(repo); if (objects_pack_dir == NULL) return got_error_from_errno("got_repo_get_path_objects_pack"); @@ -1776,6 +1780,14 @@ match_packed_object(struct got_object_id **unique_id, if (err) return err; + /* + * XXX Disable pack index refresh while we are looping and opening + * packed objects. Otherwise the packidx list we are using could be + * freed via got_object_get_type() -> ... -> got_object_open_packed() + * -> got_repo_search_packidx() -> refresh_packidx_paths(). + */ + repo->no_packidx_refresh = 1; + TAILQ_FOREACH(pe, &repo->packidx_paths, entry) { const char *path_packidx = pe->path; struct got_packidx *packidx; @@ -1822,6 +1834,7 @@ match_packed_object(struct got_object_id **unique_id, } } done: + repo->no_packidx_refresh = 0; got_object_id_queue_free(&matched_ids); if (err) { free(*unique_id);
gotwebd crash