[PATCH v3] io: Refactor {n}ftw to use fts for stack safety and conformance (BZ 33882)
Adhemerval Zanella Netto
adhemerval.zanella@linaro.org
Wed Feb 18 20:15:12 GMT 2026
On 13/02/26 14:00, Adhemerval Zanella wrote:
> The current implementation of nftw uses recursive function calls to
> traverse the directory tree. This approach is susceptible to stack
> overflow errors when traversing deeply nested directory structures,
> which can occur in legitimate workloads or be triggered by malicious
> inputs.
>
> This patch reimplements nftw on top of fts, which uses an iterative
> approach with limited stack usage. However, fts semantics differ
> slightly from glibc nftw requirements, which require some additional
> handling:
>
> * Physical Walk (FTW_PHYS) Symlink Handling, where fts checks symlink
> targets even in physical mode (FTS_PHYS), returning FTS_SLNONE for
> broken links. This requires explicitly mapping both FTS_SL and
> FTS_SLNONE to FTW_SL. nftw (physical) must report the link itself,
> regardless of the target's validity.
>
> * Logical Walk (FTS_LOGICAL) and Cycles, where fts reports directory
> cycles as FTS_DC. These are mapped to FTW_SLN (Symbolic Link that
> causes a cycle/cannot be followed), matching historical nftw behavior.
>
> * Mount Point Crossings (FTW_MOUNT), where FTS_XDEV stops fts from
> descending into mount points. In FTW_DEPTH mode, nftw requires the
> mount point directory itself to be reported, and since fts never
> enters the directory, it never generates the FTS_DP (post-order)
> event. This is fixed by capturing the root device ID, and if the
> directory is a mount point (different device ID), we treat the FTS_D
> event as the required visit and report it as FTW_DP.
>
> * Directory Changing (FTW_CHDIR), where FTS_LOGICAL implies FTS_NOCHDIR
> in fts, preventing automatic directory changes. This is implemented
> by forcing FTS_NOCHDIR for all modes to maintain consistent fts
> behavior and then manually managing FTW_CHDIR.
>
> * Root Access Errors, where fts_read returns FTS_NS if the root path
> cannot be accessed, while ftw expects a hard failure (-1) for
> permission errors on the root. This is fixed by an explicit check
> for FTS_ROOTLEVEL.
>
> * FTW_ACTIONRETVAL support, where it requires to map the FTW_SKIP_SUBTREE
> and FTW_SKIP_SIBLINGS to specific logic paths.
This strategy has some drawback, as fts FTS_LOGICAL impling in FST_NOCHDIR
which makes FTW_CHDIR potentially fail with paths longer than PATH_MAX.
There is also some corner cases for the fts that I think is not 100%
compatible, which might break some programs that rely on current semantic.
So I will drop this patch in favor on a different one that removes the
nftw recursion with a stack.
More information about the Libc-alpha
mailing list