Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-15-SP2:Update
slurm
U_06-Add-rmdir_recursive.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File U_06-Add-rmdir_recursive.patch of Package slurm
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: 71a822e22c6dcad96c81e45f55147e472c395ca6 References: CVE-2022-29500, bsc#1216207 Signed-off-by: Egbert Eich <eich@suse.de> --- src/common/fd.c | 91 +++++++++++++++++++++++++++++++++++++++++++++++ src/common/fd.h | 9 +++++ src/common/slurm_xlator.h | 1 + 3 files changed, 101 insertions(+) diff --git a/src/common/fd.c b/src/common/fd.c index 06f5d7f854..95236cf941 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> @@ -63,6 +64,7 @@ strong_alias(fd_set_nonblocking,slurm_fd_set_nonblocking); strong_alias(fd_get_socket_error, slurm_fd_get_socket_error); strong_alias(send_fd_over_pipe, slurm_send_fd_over_pipe); strong_alias(receive_fd_over_pipe, slurm_receive_fd_over_pipe); +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); @@ -364,3 +366,92 @@ extern int receive_fd_over_pipe(int socket) return fd; } + +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 ac9d680651..230dc57feb 100644 --- a/src/common/fd.h +++ b/src/common/fd.h @@ -150,4 +150,13 @@ extern char *poll_revents_to_str(const short revents); extern void send_fd_over_pipe(int socket, int fd); extern int receive_fd_over_pipe(int socket); +/* + * 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 81483be9e2..fc73d1e5b1 100644 --- a/src/common/slurm_xlator.h +++ b/src/common/slurm_xlator.h @@ -115,6 +115,7 @@ #define fd_set_nonblocking slurm_fd_set_nonblocking #define send_fd_over_pipe slurm_send_fd_over_pipe #define receive_fd_over_pipe slurm_receive_fd_over_pipe +#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