Download raw body.
tog: fix use after free of reference name
Another problem found during testing: run tog log type 'r' to open a ref view hit Enter on refs/heads/main type Ctrl-L tog exits with: tog: reference <garbage> not found Where <garbage> corresponds to memory that has been freed. It could display as an empty string, an unrelated reference name, actual garbage in the terminal, etc. This patch fixes the issue for me. ok? deep-copy reference names in the log and tree views to prevent use-after-free diff 36464f21ee78a3b85d0ab903434431af52021e5c d67a9c03480788ee66943922f80d961fa841532e blob - ba062af0078c93a3bbbfc65a63c8e30b0bdfa7f9 blob + 86a18f384a1e940617fee4f6e7a3f2df79853ac0 --- tog/tog.c +++ tog/tog.c @@ -301,7 +301,7 @@ struct tog_log_view_state { struct commit_queue_entry *selected_entry; int selected; char *in_repo_path; - const char *head_ref_name; + char *head_ref_name; int log_branches; struct got_repository *repo; struct got_reflist_head refs; @@ -396,7 +396,7 @@ struct tog_tree_view_state { int ndisplayed, selected, show_ids; struct tog_parent_trees parents; struct got_object_id *commit_id; - const char *head_ref_name; + char *head_ref_name; struct got_repository *repo; struct got_tree_entry *matched_entry; struct tog_colors colors; @@ -2110,6 +2110,8 @@ close_log_view(struct tog_view *view) s->in_repo_path = NULL; free(s->start_id); s->start_id = NULL; + free(s->head_ref_name); + s->head_ref_name = NULL; got_ref_list_free(&s->refs); return err; } @@ -2257,7 +2259,11 @@ open_log_view(struct tog_view *view, struct got_object goto done; s->repo = repo; - s->head_ref_name = head_ref_name; + s->head_ref_name = strdup(head_ref_name); + if (s->head_ref_name == NULL) { + err = got_error_from_errno("strdup"); + goto done; + } s->start_id = got_object_id_dup(start_id); if (s->start_id == NULL) { err = got_error_from_errno("got_object_id_dup"); @@ -5072,7 +5078,11 @@ open_tree_view(struct tog_view *view, struct got_tree_ err = got_error_from_errno("got_object_id_dup"); goto done; } - s->head_ref_name = head_ref_name; + s->head_ref_name = strdup(head_ref_name); + if (s->head_ref_name == NULL) { + err = got_error_from_errno("strdup"); + goto done; + } s->repo = repo; SIMPLEQ_INIT(&s->colors); @@ -5137,6 +5147,8 @@ close_tree_view(struct tog_view *view) s->tree_label = NULL; free(s->commit_id); s->commit_id = NULL; + free(s->head_ref_name); + s->head_ref_name = NULL; while (!TAILQ_EMPTY(&s->parents)) { struct tog_parent_tree *parent; parent = TAILQ_FIRST(&s->parents);
tog: fix use after free of reference name