All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mark Hatle <mark.hatle@kernel.crashing.org>
To: yocto-patches@lists.yoctoproject.org
Subject: [pseudo][PATCH 2/6] pseudo_client: Connect to the server without changing directory
Date: Thu, 12 Nov 2026 10:19:54 -0600	[thread overview]
Message-ID: <1794500398-31706-3-git-send-email-mark.hatle@kernel.crashing.org> (raw)
In-Reply-To: <1794500398-31706-1-git-send-email-mark.hatle@kernel.crashing.org>

From: Mark Hatle <mark.hatle@amd.com>

The socket paths can be too long for sun_path, so client_connect()
saved the working directory with open("."), changed to the state
directory, and changed back.  A Landlock sandbox that revokes
filesystem access, as xz sets up when working on a pipe, denies that
open(), so a process that sandboxes itself before its first pseudo
operation can never reach the server.  Name the directory as
/proc/self/fd/<fd>/ instead, which also stops connecting from moving
other threads' working directory.  Fall back to changing directory if
/proc is not mounted or the path doesn't fit in sun_path.

This makes test-landlock pass.  Both fallbacks were checked by hiding
/proc in a mount namespace and by forcing the length check to fail.

[YOCTO #16493]

AI-Generated: Uses GitHub Copilot
Signed-off-by: Mark Hatle <mark.hatle@amd.com>
---
 pseudo_client.c | 77 +++++++++++++++++++++++++++++++++++++++------------------
 1 file changed, 53 insertions(+), 24 deletions(-)

diff --git a/pseudo_client.c b/pseudo_client.c
index 58e8810..fe111cf 100644
--- a/pseudo_client.c
+++ b/pseudo_client.c
@@ -1253,8 +1253,31 @@ pseudo_client_path_matches_fd(const char *path, int fd, int nofollow) {
 static int
 client_connect(void) {
 	/* we have a server pid, is it responsive? */
-	struct sockaddr_un sun = { .sun_family = AF_UNIX, .sun_path = PSEUDO_SOCKET };
-	int cwd_fd;
+	struct sockaddr_un sun = { .sun_family = AF_UNIX };
+	struct stat st;
+	int cwd_fd = -1;
+	int use_chdir;
+	int len;
+
+	/* The full socket path can be too long for sun_path, so name the
+	 * state directory by its descriptor under /proc/self/fd.  Unlike
+	 * changing directory, that needs no open("."), which a Landlock
+	 * sandbox can deny, and doesn't move other threads' working
+	 * directory.  Without /proc, or if that path doesn't fit, change
+	 * directory as before.
+	 */
+	len = snprintf(sun.sun_path, sizeof(sun.sun_path), "/proc/self/fd/%d",
+		pseudo_localstate_dir_fd);
+	if (len > 0 && (size_t) len + 1 + strlen(PSEUDO_SOCKET) < sizeof(sun.sun_path) &&
+	    stat(sun.sun_path, &st) == 0 && S_ISDIR(st.st_mode)) {
+		snprintf(sun.sun_path + len, sizeof(sun.sun_path) - len, "/%s",
+			PSEUDO_SOCKET);
+		use_chdir = 0;
+	} else {
+		pseudo_debug(PDBGF_CLIENT, "/proc/self/fd unusable or path too long, changing directory to connect.\n");
+		snprintf(sun.sun_path, sizeof(sun.sun_path), "%s", PSEUDO_SOCKET);
+		use_chdir = 1;
+	}
 
 	connect_fd = socket(PF_UNIX, SOCK_STREAM, 0);
 	connect_fd = pseudo_fd(connect_fd, MOVE_FD);
@@ -1267,40 +1290,46 @@ client_connect(void) {
 	}
 
 	pseudo_debug(PDBGF_CLIENT, "connecting socket...\n");
-	cwd_fd = open(".", O_RDONLY);
-	if (cwd_fd == -1) {
-		pseudo_error("Couldn't stash directory before opening socket: %s",
-			strerror(errno));
-		close(connect_fd);
-		connect_fd = -1;
-		return 1;
-	}
-	if (fchdir(pseudo_localstate_dir_fd) == -1) {
-		pseudo_error("Couldn't chdir to server directory [%d]: %s\n",
-			pseudo_localstate_dir_fd, strerror(errno));
-		close(connect_fd);
-		close(cwd_fd);
-		connect_fd = -1;
-		return 1;
+	if (use_chdir) {
+		cwd_fd = open(".", O_RDONLY);
+		if (cwd_fd == -1) {
+			pseudo_error("Couldn't stash directory before opening socket: %s\n",
+				strerror(errno));
+			close(connect_fd);
+			connect_fd = -1;
+			return 1;
+		}
+		if (fchdir(pseudo_localstate_dir_fd) == -1) {
+			pseudo_error("Couldn't chdir to server directory [%d]: %s\n",
+				pseudo_localstate_dir_fd, strerror(errno));
+			close(connect_fd);
+			close(cwd_fd);
+			connect_fd = -1;
+			return 1;
+		}
 	}
 	if (connect(connect_fd, (struct sockaddr *) &sun, sizeof(sun)) == -1) {
 		char *e = strerror(errno);
 		pseudo_debug(PDBGF_CLIENT, "Can't connect socket to pseudo.socket: (%s)\n", e);
 		pseudo_evlog(PDBGF_CLIENT, "connect failed: %s\n", e);
 		close(connect_fd);
+		if (use_chdir) {
+			if (fchdir(cwd_fd) == -1) {
+				pseudo_error("return to previous directory failed: %s\n",
+					strerror(errno));
+			}
+			close(cwd_fd);
+		}
+		connect_fd = -1;
+		return 1;
+	}
+	if (use_chdir) {
 		if (fchdir(cwd_fd) == -1) {
 			pseudo_error("return to previous directory failed: %s\n",
 				strerror(errno));
 		}
 		close(cwd_fd);
-		connect_fd = -1;
-		return 1;
-	}
-	if (fchdir(cwd_fd) == -1) {
-		pseudo_error("return to previous directory failed: %s\n",
-			strerror(errno));
 	}
-	close(cwd_fd);
 	pseudo_evlog(PDBGF_CLIENT, "socket connect OK.\n");
 	pseudo_debug(PDBGF_CLIENT | PDBGF_VERBOSE, "connected socket.\n");
 	return 0;
-- 
1.8.3.1


  parent reply	other threads:[~2026-11-12 16:20 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-12 16:19 [pseudo][PATCH 0/6] Add landlock support, fix seccomp Mark Hatle
2026-11-12 16:19 ` [pseudo][PATCH 1/6] test-landlock: Add a Landlock sandbox test Mark Hatle
2026-11-12 16:19 ` Mark Hatle [this message]
2026-11-12 16:19 ` [pseudo][PATCH 3/6] ports/linux/pseudo_wrappers: Report Landlock as unsupported Mark Hatle
2026-11-12 16:19 ` [pseudo][PATCH 4/6] test-seccomp: Check that seccomp is never really enabled Mark Hatle
2026-11-12 16:19 ` [pseudo][PATCH 5/6] ports/linux/pseudo_wrappers: Fake seccomp filters set by prctl() Mark Hatle
2026-11-12 16:19 ` [pseudo][PATCH 6/6] ports/linux/pseudo_wrappers: Fake seccomp strict mode in syscall() Mark Hatle

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1794500398-31706-3-git-send-email-mark.hatle@kernel.crashing.org \
    --to=mark.hatle@kernel.crashing.org \
    --cc=yocto-patches@lists.yoctoproject.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.