Subject: bug#31439: Possible memory leak in fts.c

From: Pádraig Brady <[email-masked]>
Date: Sun, 13 May 2018 17:53:46 -0700

On 12/05/18 18:50, ISE Development wrote:
> Hi,
> 
> I may be wrong but I suspect there is a corner case where fts_close()
> will not free the FTSENT structures correctly if called immediately
> after fts_open().
> 
> After fts_open(), the current entry is a dummy entry created as
> follows:
> 
> if ((sp->fts_cur = fts_alloc(sp, "", 0)) == NULL)
>         goto mem3;
> sp->fts_cur->fts_link = root;
> sp->fts_cur->fts_info = FTS_INIT;
> 
> It would normally be freed during the first invocation of fts_read().
> 
> In fts_close():
> 
> if (sp->fts_cur) {
>         for (p = sp->fts_cur; p->fts_level >= FTS_ROOTLEVEL;) {
>                 freep = p;
>                 p = p->fts_link != NULL ? p->fts_link : p->fts_parent;
>                 free(freep);
>         }
>         free(p);
> }
> 
> However, fts_alloc() does not clear or set fts_level, nor does it zero
> the entire FTSENT structure.
> 
> So as far as I can figure, it is possible for the fts_level of the
> dummy entry to be negative after fts_open() causing fts_close() not to
> free the actual root level entries.

valgrind should tell us. I tweaked chmod to call fts_close()
right after xfts_open() and got:

==21011== Conditional jump or move depends on uninitialised value(s)
==21011==    at 0x4066C6: fts_close (fts.c:609)
==21011==    by 0x401B7F: process_files (chmod.c:337)
==21011==    by 0x401B7F: main (chmod.c:572)

Just as you surmised.

Patch coming up... (to gnulib)

thanks!
Pádraig