diff mbox series

[pseudo,2/3] pseudo_client: step around all of pseudo's own fds in closefrom/close_range

Message ID 20260718043750.7-3-bbnpreetsingh@gmail.com
State New
Headers show
Series closefrom/close_range: protect every pseudo fd, then drop one | expand

Commit Message

Babanpreet Singh July 18, 2026, 4:37 a.m. UTC
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 <bbnpreetsingh@gmail.com>
---
 pseudo.h        |  1 +
 pseudo_client.c | 20 ++++++++++++++++++--
 2 files changed, 19 insertions(+), 2 deletions(-)
diff mbox series

Patch

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);