Re: [PATCH 2/3] dir: make clear_directory() free all relevant memory

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sun, Aug 16, 2020 at 1:54 AM Jeff King <peff@xxxxxxxx> wrote:
>
> On Sun, Aug 16, 2020 at 06:59:10AM +0000, Elijah Newren via GitGitGadget wrote:
>
> > From: Elijah Newren <newren@xxxxxxxxx>
> >
> > The calling convention for the dir API is supposed to end with a call to
> > clear_directory() to free up no longer needed memory.  However,
> > clear_directory() didn't free dir->entries or dir->ignored.  I believe
> > this was oversight, but a number of callers noticed memory leaks and
> > started free'ing these, but often somewhat haphazardly (sometimes
> > freeing the entries in the arrays, and sometimes only free'ing the
> > arrays themselves).  This suggests the callers weren't trying to make
> > sure any possible memory used might be free'd, but just the memory they
> > noticed their usecase definitely had allocated.  This also caused the
> > extra memory deallocations to be duplicated in many places.
> >
> > Fix this mess by moving all the duplicated free'ing logic into
> > clear_directory().
>
> Makes sense. I don't know the dir.c code very well, so my worry would be
> that some caller really wanted the other fields left untouched. But
> looking over the callers, it seems they're all clearing it before the
> struct goes out of scope. It's possible that they could have created
> other pointer references, but it seems unlikely (and I'd argue they
> should stop doing that and make their own copies of the data). E.g.,
> wt_status_collect_untracked() sticks names into a string_list, but it
> sets strdup_strings to make its own copy, so it's good.
>
> > @@ -3034,6 +3031,13 @@ void clear_directory(struct dir_struct *dir)
> >               free(group->pl);
> >       }
> >
> > +     for (i = 0; i < dir->ignored_nr; i++)
> > +             free(dir->ignored[i]);
> > +     for (i = 0; i < dir->nr; i++)
> > +             free(dir->entries[i]);
> > +     free(dir->ignored);
> > +     free(dir->entries);
> > +
> >       stk = dir->exclude_stack;
> >       while (stk) {
> >               struct exclude_stack *prev = stk->prev;
>
> In most of our "clear" functions, the struct is ready for use again
> (i.e., fields are set back to the initialized state). I don't think any
> caller cares at this point, but it may be worth doing while we are here
> as a least-surprise thing. That would mean setting these pointers to
> NULL, and probably a few others that you aren't touching here.
>
> Perhaps even easier would be to add a dir_init() call at the end after
> your next patch adds that function.

Make sense; I'll fix it up.



[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux