Re: [PATCH] revision: fix missing null for freed memory
On Mon, Feb 10, 2025 at 8:02 AM Junio C Hamano <gitster@pobox.com> wrote:
Show 13 quoted lines
>
> Emily M Klassen <forivall@gmail.com> writes:
>
> > Subject: Re: [PATCH] revision: fix missing null for freed memory
> >
> > "git log --graph --no-graph" missed cleaning up the output_prefix and
> > output_prefix_data pointers. This resulted in a segfault when using "--patch",
> > "--name-status" or "--name-only", as the output_prefix_data continued to be in
> > use after free()
>
> Rereading the title, I cannot make sense out of "fix missing null"
> and guess what it wants to say. Is "null" here used as a verb to
> mean "to assign a NULL to a variable that points at ..."?
Yeah, this was meant to say something like "fix missing null assignment after freeing graph data", and I didn't really have the energy to think of a better summary at the time.
Show 14 quoted lines
>
> revision: clear graph callback upon "--no-graph"
>
> "git log --graph --no-graph" first populates the .output_prefix
> member of diffopt, which is a callback function, to compute
> "--graph" header, and then discards the data the callback needs
> to compute the graph header but forgets to clear .output_prefix
> pointer in response to "--no-graph". At runtime, we end up
> calling the function that we should not.
>
> Clear the member to stop making callback, and for a better
> hyginene, also clear the pointer pointing at a freed memory.
>
> or something?
Yup, this works well. A small bit of rephrasing for readability:
revision: clear graph prefix callback upon "--no-graph"
"git log --graph --no-graph" misses some cleanup: handling
"--graph", it assigns the .output_prefix member of diffopt, which
is a callback function to compute the graph prefix when displaying
a diff. Then, when handling "--no-graph" it discards the data the
callback needs to compute the graph header but forgets to clear
.output_prefix pointer. At runtime, we call the function when we
should not. It also passes a stale pointer to the data, which leads
to a segfault when the callback is used for "--patch",
"--name-status" or "--name-only". Clear the member to stop the callback from being called, and for
hygiene, also clear the pointer pointing at a freed memory.>
> Other than that, as I said earlier, the patch looks good.
>
> Thanks.
Awesome. I'll also add a test before re-submitting, as mentioned in your other message.
Thanks for the feedback!
Show 22 quoted lines
>
> > Signed-off-by: Emily M Klassen <forivall@gmail.com>
> > ---
> > I previously reported this a few hours ago, and ended up digging in and figuring
> > it out. I'll make sure to bottom reply in the follow ups to this patch.
> >
> > revision.c | 2 ++
> > 1 file changed, 2 insertions(+)
> >
> > diff --git a/revision.c b/revision.c
> > index 474fa1e767..84cb028e11 100644
> > --- a/revision.c
> > +++ b/revision.c
> > @@ -2615,6 +2615,8 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg
> > graph_clear(revs->graph);
> > revs->graph = graph_init(revs);
> > } else if (!strcmp(arg, "--no-graph")) {
> > + revs->diffopt.output_prefix = NULL;
> > + revs->diffopt.output_prefix_data = NULL;
> > graph_clear(revs->graph);
> > revs->graph = NULL;
> > } else if (!strcmp(arg, "--encode-email-headers")) {