From: Christian Weisgerber Subject: tog tree double free To: gameoftrees@openbsd.org Date: Sat, 10 Jul 2021 17:05:30 +0200 I can reliably crash tog on OpenBSD src.git. * Start tog tree, pick any file that has been there since the initial import, e.g.: tog tree -r src.git bin/sync/sync.c * Hit 'l' to open a log view. * Select the earliest commit, "initial import of NetBSD tree". * Hit ENTER to open a diff view. * Hit 'q' three times to exit. After the third 'q', tog crashes with a double free(). You can also use the 'Q' shortcut. The culprit is the got_object_tree_close(tree) call at the tail end of cmd_tree(). "tree" points to free'd memory. With some instrumentation: close_tree_view -> got_object_tree_close: 0x42cd5ddffa0, refcnt=1 cmd_tree -> got_object_tree_close: 0x42cd5ddffa0, refcnt=-538976289 tog(46766) in free(): bogus pointer (double free?) 0xdfdfdfdfdfdfdfdf Abort trap Both close_tree_view() and cmd_tree() closing the same tree seems suspicious. But that also happens when tog doesn't crash, hmm: close_tree_view -> got_object_tree_close: 0x2abeea04640, refcnt=2 cmd_tree -> got_object_tree_close: 0x2abeea04640, refcnt=1 Maybe there's a problem with the ref counting? open_tree() increments tree->refcnt and then calls got_repo_cache_tree(), which increments it again... and I'm already confused. -- Christian "naddy" Weisgerber naddy@mips.inka.de