Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Leap:15.3
slurm.31097
U_06-Add-rmdir_recursive.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File U_06-Add-rmdir_recursive.patch of Package slurm.31097
From: Tim Wickberg <tim@schedmd.com> Date: Wed Oct 11 12:45:25 2023 -0600 Subject: [PATCH 6/19]Add rmdir_recursive(). Patch-mainline: Upstream Git-repo: https://github.com/SchedMD/slurm Git-commit: 2f4fc8aedf181f182fd9bbcdbf7950c602c6db24 References: bsc#1216207,CVE-2023-41914 Signed-off-by: Egbert Eich <eich@suse.de> --- src/common/fd.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++- src/common/fd.h | 9 +++++ src/common/slurm_xlator.h | 1 + 3 files changed, 101 insertions(+), 1 deletion(-) diff --git a/src/common/fd.c b/src/common/fd.c index 09a386ecce..103fe441a2 100644 --- a/src/common/fd.c +++ b/src/common/fd.c @@ -35,6 +35,7 @@ * Refer to "fd.h" for documentation on public functions. \*****************************************************************************/ +#include <dirent.h> #include <assert.h> #include <errno.h> #include <fcntl.h> @@ -53,7 +54,7 @@ strong_alias(fd_read_n, slurm_fd_read_n); strong_alias(fd_write_n, slurm_fd_write_n); strong_alias(fd_set_blocking, slurm_fd_set_blocking); strong_alias(fd_set_nonblocking,slurm_fd_set_nonblocking); - +strong_alias(rmdir_recursive, slurm_rmdir_recursive); static int fd_get_lock(int fd, int cmd, int type); static pid_t fd_test_lock(int fd, int type); @@ -237,3 +238,92 @@ extern int wait_fd_readable(int fd, int time_limit) } } } + +static int _rmdir_recursive(int dirfd) +{ + int rc = 0; + DIR *dp; + struct dirent *ent; + + if (!(dp = fdopendir(dirfd))) { + error("%s: can't open directory: %m", __func__); + return 1; + } + + while ((ent = readdir(dp))) { + int childfd = -1; + + /* skip special directories */ + if (!strcmp(ent->d_name, ".") || + !strcmp(ent->d_name, "..")) { + continue; + } + + /* try to remove entry, first as a file, then as a directory */ + if (unlinkat(dirfd, ent->d_name, 0) != -1) { + debug("%s: removed file `%s`", __func__, ent->d_name); + continue; + } else if (unlinkat(dirfd, ent->d_name, AT_REMOVEDIR) != -1) { + debug("%s: removed empty directory `%s`", + __func__, ent->d_name); + continue; + } + + /* removal didn't work. assume it's a non-empty directory */ + if ((childfd = openat(dirfd, ent->d_name, + (O_DIRECTORY | O_NOFOLLOW))) < 0) { + debug("%s: openat() failed for `%s`: %m", + __func__, ent->d_name); + rc++; + continue; + } + + debug("%s: descending into directory `%s`", + __func__, ent->d_name); + rc += _rmdir_recursive(childfd); + (void) close(childfd); + + if (unlinkat(dirfd, ent->d_name, AT_REMOVEDIR) != -1) { + debug("%s: removed now-empty directory `%s`", + __func__, ent->d_name); + } else { + debug("%s: unlinkat() failed for `%s`: %m", + __func__, ent->d_name); + rc++; + } + } + closedir(dp); + + return rc; +} + +extern int rmdir_recursive(const char *path, bool remove_top) +{ + int rc = 0; + int dirfd; + + if ((dirfd = open(path, O_DIRECTORY | O_NOFOLLOW)) < 0) { + error("%s: could not open %s", __func__, path); + return 1; + } + + rc = _rmdir_recursive(dirfd); + close(dirfd); + + if (remove_top) { + if (rmdir(path) < 0) { + debug("%s: rmdir() failed for `%s`: %m", + __func__, path); + rc++; + } else { + debug("%s: removed now-empty top directory `%s`", + __func__, path); + } + } + + if (rc) + error("%s: could not completely remove `%s`, %d files left", + __func__, path, rc); + + return rc; +} diff --git a/src/common/fd.h b/src/common/fd.h index 4505d6dce6..46f7b5b859 100644 --- a/src/common/fd.h +++ b/src/common/fd.h @@ -130,4 +130,13 @@ extern int wait_fd_readable(int fd, int time_limit); /* Wait for a file descriptor to be readable (up to time_limit seconds). * Return 0 when readable or -1 on error */ +/* + * Recursively remove a directory and all contents. + * Takes care not to follow any symlinks outside the target directory. + * + * Returns the number of files/directories it failed to remove, + * or 0 on success. + */ +extern int rmdir_recursive(const char *path, bool remove_top); + #endif /* !_FD_H */ diff --git a/src/common/slurm_xlator.h b/src/common/slurm_xlator.h index 8f2516686a..832b1a0dad 100644 --- a/src/common/slurm_xlator.h +++ b/src/common/slurm_xlator.h @@ -115,6 +115,7 @@ #define fd_write_n slurm_fd_write_n #define fd_set_blocking slurm_fd_set_blocking #define fd_set_nonblocking slurm_fd_set_nonblocking +#define rmdir_recursive slurm_rmdir_recursive /* hostlist.[ch] functions */ #define hostlist_create slurm_hostlist_create
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor