"GOT", but the "O" is a cute, smiling pufferfish. Index | Thread | Search

From:
Christian Weisgerber <naddy@mips.inka.de>
Subject:
tog tree double free
To:
gameoftrees@openbsd.org
Date:
Sat, 10 Jul 2021 17:05:30 +0200

Download raw body.

Thread
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