shared/rm-rf: loop over nested directories instead of instead of recursing
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Tue, 30 Nov 2021 21:29:05 +0000 (22:29 +0100)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Tue, 11 Jan 2022 19:16:31 +0000 (20:16 +0100)
commit6a28f8b55904c818b25e4db2e1511faac79fd471
tree44d1ddaa8aa17056d73e97e524ba47ba1ab2ff1a
parent811b137d6137cc3e8932599e6ef9254ba43ff5eb
shared/rm-rf: loop over nested directories instead of instead of recursing

To remove directory structures, we need to remove the innermost items first,
and then recursively remove higher-level directories. We would recursively
descend into directories and invoke rm_rf_children and rm_rm_children_inner.
This is problematic when too many directories are nested.

Instead, let's create a "TODO" queue. In the the queue, for each level we
hold the DIR* object we were working on, and the name of the directory. This
allows us to leave a partially-processed directory, and restart the removal
loop one level down. When done with the inner directory, we use the name to
unlinkat() it from the parent, and proceed with the removal of other items.

Because the nesting is increased by one level, it is best to view this patch
with -b/--ignore-space-change.

This fixes CVE-2021-3997, https://bugzilla.redhat.com/show_bug.cgi?id=2024639.
The issue was reported and patches reviewed by Qualys Team.
Mauro Matteo Cascella and Riccardo Schirone from Red Hat handled the disclosure.

(cherry picked from commit 5b1cf7a9be37e20133c0208005274ce4a5b5c6a1)
(cherry picked from commit 911516e1614e435755814ada5fc6064fa107a105)
src/shared/rm-rf.c