1
0
mirror of https://github.com/systemd/systemd.git synced 2025-03-19 22:50:17 +03:00

Add variant of close_all_fds() that does not allocate and use it in freeze()

Even though it's just a fallback path, let's not be sloppy and allocate in
the crash handler.

> The deadlock happens because systemd crash in malloc() then in signal
> handler, it calls malloc() (close_all_fds()-> opendir()-> __alloc_dir())
> again. malloc() is not a signal-safe function, maybe we should re-think
> the logic here.

Fixes #20266.
This commit is contained in:
Zbigniew Jędrzejewski-Szmek 2021-07-23 11:36:44 +02:00
parent 45a68ed307
commit cbcf371abc
3 changed files with 9 additions and 6 deletions

View File

@ -208,7 +208,7 @@ static int get_max_fd(void) {
return (int) (m - 1);
}
int close_all_fds(int except[], size_t n_except) {
int close_all_fds_full(int except[], size_t n_except, bool allow_alloc) {
static bool have_close_range = true; /* Assume we live in the future */
_cleanup_closedir_ DIR *d = NULL;
int r = 0;
@ -274,7 +274,7 @@ int close_all_fds(int except[], size_t n_except) {
/* Fallback for when close_range() is not supported */
opendir_fallback:
d = opendir("/proc/self/fd");
d = allow_alloc ? opendir("/proc/self/fd") : NULL;
if (d) {
struct dirent *de;
@ -302,8 +302,8 @@ int close_all_fds(int except[], size_t n_except) {
return r;
}
/* Fallback for when /proc isn't available (for example in chroots) by brute-forcing through the file
* descriptor table. */
/* Fallback for when /proc isn't available (for example in chroots) or when we cannot allocate by
* brute-forcing through the file descriptor table. */
int max_fd = get_max_fd();
if (max_fd < 0)

View File

@ -56,7 +56,10 @@ DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(DIR*, closedir, NULL);
int fd_nonblock(int fd, bool nonblock);
int fd_cloexec(int fd, bool cloexec);
int close_all_fds(int except[], size_t n_except);
int close_all_fds_full(int except[], size_t n_except, bool allow_alloc);
static inline int close_all_fds(int except[], size_t n_except) {
return close_all_fds_full(except, n_except, true);
}
int same_fd(int a, int b);

View File

@ -452,7 +452,7 @@ _noreturn_ void freeze(void) {
log_close();
/* Make sure nobody waits for us on a socket anymore */
(void) close_all_fds(NULL, 0);
(void) close_all_fds_full(NULL, 0, false);
sync();