[pseudo] [PATCH 2/3] pseudo_client: step around all of pseudo's own fds in closefrom/close_range
Babanpreet Singh <[email protected]> Sat, 18 Jul 2026 04:37:49 +0000
| Newsgroups | org.yoctoproject.lists.yocto-patches |
|---|---|
| Message-ID | <[email protected]> |
OP_CLOSEFROM and OP_CLOSE_RANGE step around five descriptors pseudo keeps for itself (debug output, the local state directory, passwd, group, and the server connection), but pseudo can hold three more, and a sweep will close those: - pseudo_util_evlog_fd is where pseudo_evlog_dump() writes the in-memory event log at the moment the client gives up on the server connection for good. It defaults to 2, so stepping around it matches the existing treatment of pseudo_util_debug_fd, which also defaults to 2 and is already protected. A closed (or worse, silently reused) descriptor here would misdirect exactly the diagnostics needed to debug a dead server. - pseudo_pwd_lck_fd is open between lckpwdf() and ulckpwdf(), which is precisely the window in which a caller works on the passwd files and may sweep descriptors. Once the sweep has closed it, ulckpwdf()'s close() can land on an unrelated descriptor that reused the number. - pseudo_prefix_dir_fd is opened at client init and stays open for the life of the process. pseudo_pwd_lck_fd is -1 while no lock is held, which the existing pattern already copes with: -1 never raises startfd and never matches a descriptor the close-by-hand loop visits. pseudo_util_evlog_fd had no declaration outside pseudo_util.c, so give it one in pseudo.h next to pseudo_util_debug_fd. [YOCTO #16339] AI-Generated: Uses Claude (claude-sonnet-5) Signed-off-by: Babanpreet Singh <[email protected]> --- pseudo.h | 1 + pseudo_client.c | 20 ++++++++++++++++++-- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/pseudo.h b/pseudo.h index b6c13f2..44ee991 100644 --- a/pseudo.h +++ b/pseudo.h @@ -29,6 +29,7 @@ extern void pseudo_debug_flags_finalize(void); extern unsigned long pseudo_util_debug_flags; extern unsigned long pseudo_util_evlog_flags; extern int pseudo_util_debug_fd; +extern int pseudo_util_evlog_fd; extern int pseudo_disabled; extern int pseudo_allow_fsync; extern int pseudo_diag(char *, ...) __attribute__ ((format (printf, 1, 2))); diff --git a/pseudo_client.c b/pseudo_client.c index 085a8b3..7f80a3b 100644 --- a/pseudo_client.c +++ b/pseudo_client.c @@ -1968,16 +1968,24 @@ pseudo_client_op(pseudo_op_t op, int access, int fd, int dirfd, const char *path startfd = fd; if (pseudo_util_debug_fd >= startfd) startfd = pseudo_util_debug_fd + 1; + if (pseudo_util_evlog_fd >= startfd) + startfd = pseudo_util_evlog_fd + 1; + if (pseudo_prefix_dir_fd >= startfd) + startfd = pseudo_prefix_dir_fd + 1; if (pseudo_localstate_dir_fd >= startfd) startfd = pseudo_localstate_dir_fd + 1; if (pseudo_pwd_fd >= startfd) startfd = pseudo_pwd_fd + 1; + if (pseudo_pwd_lck_fd >= startfd) + startfd = pseudo_pwd_lck_fd + 1; if (pseudo_grp_fd >= startfd) startfd = pseudo_grp_fd + 1; if (connect_fd >= startfd) startfd = connect_fd + 1; for (i = fd; i < startfd; ++i) { - if (i == pseudo_util_debug_fd || i == pseudo_localstate_dir_fd || i == pseudo_pwd_fd || + if (i == pseudo_util_debug_fd || i == pseudo_util_evlog_fd || + i == pseudo_prefix_dir_fd || i == pseudo_localstate_dir_fd || + i == pseudo_pwd_fd || i == pseudo_pwd_lck_fd || i == pseudo_grp_fd || i == connect_fd) continue; pseudo_client_close(i); @@ -1994,10 +2002,16 @@ pseudo_client_op(pseudo_op_t op, int access, int fd, int dirfd, const char *path startfd = fd; if (pseudo_util_debug_fd >= startfd) startfd = pseudo_util_debug_fd + 1; + if (pseudo_util_evlog_fd >= startfd) + startfd = pseudo_util_evlog_fd + 1; + if (pseudo_prefix_dir_fd >= startfd) + startfd = pseudo_prefix_dir_fd + 1; if (pseudo_localstate_dir_fd >= startfd) startfd = pseudo_localstate_dir_fd + 1; if (pseudo_pwd_fd >= startfd) startfd = pseudo_pwd_fd + 1; + if (pseudo_pwd_lck_fd >= startfd) + startfd = pseudo_pwd_lck_fd + 1; if (pseudo_grp_fd >= startfd) startfd = pseudo_grp_fd + 1; if (connect_fd >= startfd) @@ -2006,7 +2020,9 @@ pseudo_client_op(pseudo_op_t op, int access, int fd, int dirfd, const char *path * with, so close those by hand and skip the ones we need */ for (i = fd; i < startfd && (unsigned int) i <= close_range_maxfd; ++i) { - if (i == pseudo_util_debug_fd || i == pseudo_localstate_dir_fd || i == pseudo_pwd_fd || + if (i == pseudo_util_debug_fd || i == pseudo_util_evlog_fd || + i == pseudo_prefix_dir_fd || i == pseudo_localstate_dir_fd || + i == pseudo_pwd_fd || i == pseudo_pwd_lck_fd || i == pseudo_grp_fd || i == connect_fd) continue; pseudo_client_close(i); -- 2.43.0