]> git.ipfire.org Git - thirdparty/util-linux.git/commit
switch_root: unlink files without _DIRENT_HAVE_D_TYPE
authorPatrick Steinhardt <ps@pks.im>
Sun, 23 Apr 2017 00:33:04 +0000 (02:33 +0200)
committerKarel Zak <kzak@redhat.com>
Wed, 26 Apr 2017 09:23:50 +0000 (11:23 +0200)
commit85bfb519afcbccccb63849b1a348dde76ff6bb83
treef0658d01ddbeae9813977c9c73ba034ab2cd8162
parent97fc6ccf791fc44f945f779608051a7bd3b6ea65
switch_root: unlink files without _DIRENT_HAVE_D_TYPE

When _DIRENT_HAVE_D_TYPE is not defined, we need to always fstat the
directory entry in order to determine whether it is a directory or not.
If we determine that the file is indeed a directory on the same device,
we proceed to recursively remove its contents as well. Otherwise, we
simply skip removing the entry altogether.

This logic is not entirely correct though. Note that we actually skip
deletion of the entry if it is either not a directory or if it is not on
the same device. The second condition is obviously correct here, as we
do not want to delete files on other mounts here. But skipping deletion
of the entry itself if it is not a directory is wrong.

When _DIRENT_HAVE_D_TYPE is defined, this condition should never be
triggered, as we have already determined that the entry is a directory.
But if it is not, we will always do the fstat and check. Because of
this, we will now skip deletion of all files which are not directories,
which is wrong.

Fix the issue by disentangling both conditions. We now first check
whether we are still on the same device - if not, we skip recursive
deletion as well as deletion of the directory entry. Afterwards, we
check whether it is a directory - if so, we do delete its contents
recursively. And finally, we will now unlink the entry disregarding
whether it is a directory or not.

Signed-off-by: Patrick Steinhardt <ps@pks.im>
sys-utils/switch_root.c