From 22bfd3a8a6e099f267feab21f66d0d1e2b6acf60 Mon Sep 17 00:00:00 2001 From: "Anna (navi) Figueiredo Gomes" Date: Sun, 29 Jun 2025 01:59:12 +0200 Subject: [PATCH] librc: clear dirfds when creating new svcdir if for whatever reason, /run/openrc exists in the rootfs before first boot, we'd still end up with an invalid fd. while users are not really supposed to have anything in /run (under the tmpfs mount), should they do, it's better to not fail clearing the dirfds as we create svcdir also means we don't need a new librc api function to clear it, for now at least. --- src/librc/librc-depend.c | 4 +++- src/librc/librc.c | 22 +++++++++++++--------- src/librc/librc.h | 1 + 3 files changed, 17 insertions(+), 10 deletions(-) diff --git a/src/librc/librc-depend.c b/src/librc/librc-depend.c index 693037498..2ee2dd4d3 100644 --- a/src/librc/librc-depend.c +++ b/src/librc/librc-depend.c @@ -693,7 +693,9 @@ rc_deptree_update_needed(time_t *newest, char *file) /* Quick test to see if anything we use has changed and we have * data in our deptree. */ - if (mkdir(rc_svcdir(), 0755) != 0 && errno != EEXIST) + if (mkdir(rc_svcdir(), 0755) == 0) + clear_dirfds(); /* clear our cached dirfds if we created a new svcdir, as a sanity check */ + else if (errno != EEXIST) fprintf(stderr, "mkdir '%s': %s\n", rc_svcdir(), strerror(errno)); if (fstatat(rc_dirfd(RC_DIR_SVCDIR), "deptree", &buf, 0) == 0) { diff --git a/src/librc/librc.c b/src/librc/librc.c index c68b14db7..6e06b0f60 100644 --- a/src/librc/librc.c +++ b/src/librc/librc.c @@ -80,6 +80,18 @@ int rc_dirfd(enum rc_dir dir) { return dirfds[dir]; } +void clear_dirfds(void) { + for (size_t i = 0; i < RC_DIR_MAX; i++) { + /* dirfd is zero-initialized, though zero is a valid + * FD, dirfd should never contain FDs which are <= 2. */ + if (dirfds[i] <= 0) + continue; + + close(dirfds[i]); + dirfds[i] = -1; + } +} + #define LS_INITD 0x01 #define LS_DIR 0x02 static RC_STRINGLIST * @@ -633,15 +645,7 @@ rc_set_user(void) rc_dirs.scriptdirs[SCRIPTDIR_USR] = rc_dirs.usrconfdir; rc_dirs.scriptdirs[SCRIPTDIR_SVC] = rc_dirs.svcdir; - for (size_t i = 0; i < RC_DIR_MAX; i++) { - /* dirfd is zero-initialized, though zero is a valid - * FD, dirfd should never contain FDs which are <= 2. */ - if (dirfds[i] <= 0) - continue; - - close(dirfds[i]); - dirfds[i] = -1; - } + clear_dirfds(); } const char * const * diff --git a/src/librc/librc.h b/src/librc/librc.h index 65c11cea7..d49dd849a 100644 --- a/src/librc/librc.h +++ b/src/librc/librc.h @@ -73,5 +73,6 @@ static const char *const dirnames[RC_DIR_SYS_MAX] = }; RC_STRINGLIST *config_list(int dirfd, const char *pathname); +void clear_dirfds(void); #endif