[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