[PATCH v2 03/10] sandbox/seunshare: cap rm_rf() depth

Stephen Smalley <[email protected]>
Newsgroups org.kernel.vger.selinux
Message-ID <[email protected]>
Cap the depth for rm_rf() descent to prevent hitting EMFILE
or stack exhaustion. Failure to fully remove the temporary
directory was already non-fatal and harmless.

Signed-off-by: Stephen Smalley <[email protected]>
---
 sandbox/seunshare.c | 12 +++++++++---
 1 file changed, 9 insertions(+), 3 deletions(-)

diff --git a/sandbox/seunshare.c b/sandbox/seunshare.c
index d0f3ef1f..1e7822e5 100644
--- a/sandbox/seunshare.c
+++ b/sandbox/seunshare.c
@@ -485,7 +485,8 @@ err:
  *         a non-root user: symbolic links to root paths (such as /root) will
  *         not be followed.
  */
-static bool rm_rf(int targetfd, const char *path)
+#define RM_RF_MAXDEPTH 128
+static bool rm_rf(int targetfd, const char *path, unsigned int depth)
 {
 	struct stat statbuf;
 
@@ -498,6 +499,11 @@ static bool rm_rf(int targetfd, const char *path)
 	}
 
 	if (S_ISDIR(statbuf.st_mode)) {
+		if (depth >= RM_RF_MAXDEPTH) {
+			fprintf(stderr,
+				_("rm_rf: directory tree too deep, giving up\n"));
+			return false;
+		}
 		const int newfd =
 			openat(targetfd, path,
 			       O_RDONLY | O_DIRECTORY | O_NOFOLLOW | O_CLOEXEC);
@@ -521,7 +527,7 @@ static bool rm_rf(int targetfd, const char *path)
 				continue;
 			}
 
-			if (!rm_rf(dirfd(dir), entry->d_name)) {
+			if (!rm_rf(dirfd(dir), entry->d_name, depth + 1)) {
 				rc = false;
 			}
 		}
@@ -628,7 +634,7 @@ static int cleanup_tmpdir(const char *tmpdir, const char *src,
 		rc++;
 
 	/* Recursively remove the runtime temp directory.  */
-	if (!rm_rf(AT_FDCWD, tmpdir)) {
+	if (!rm_rf(AT_FDCWD, tmpdir, 0)) {
 		fprintf(stderr,
 			_("Failed to recursively remove directory %s\n"),
 			tmpdir);
-- 
2.55.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.