diff mbox series

[pseudo] pseudo_util.c: Skip realpath like expansion for /proc

Message ID 1766444053-25346-1-git-send-email-mark.hatle@kernel.crashing.org
State New
Headers show
Series [pseudo] pseudo_util.c: Skip realpath like expansion for /proc | expand

Commit Message

Mark Hatle Dec. 22, 2025, 10:54 p.m. UTC
From: Mark Hatle <mark.hatle@amd.com>

See: Yocto Project bugzilla 16028

Gauthier HADERER (see comment 23) reported an issue where realpath like
behavior of pseudo_fix_path function resulted in a failure of the rust
based tail command.

It was determined that the behavior could be emulated by doing:

echo "test" | tail /dev/fd/0

(tail, cat or any other similar command would result in the same failure)

This results in:
  /dev/fd/0 -> /proc/self/fd/0
  /proc/self/fd/0 -> /proc/1475524/fd/0
  /proc/1475524/fd/0 -> /proc/1475524/fd/pipe:[1177004485]

with an eventual failure of unable to open /proc/1475524/fd/pipe:[1177004485]

This change resolves the issue by detecting the path has been resolved into
the /proc filesystem and then forcing the system to stop resolving
additional path elements.  This ensures that special /proc behavior can be
maintained.

It is still unclear to me why the original code path fails, but in proc
there is clearly a symlink for the pipe, but the pipe itself is not present
which is triggering the failure condition.  Accessing the pipe via
/proc/self/fd/0 appears to work reliably and consistently while not
introducing issues with the special path resolution required for chroot
emulation.

Reported-by: Gauthier HADERER <ghaderer@wyplay.com>

Signed-off-by: Mark Hatle <mark.hatle@amd.com>
Signed-off-by: Mark Hatle <mark.hatle@kernel.crashing.org>
---
 pseudo_util.c          | 15 +++++++++++++++
 test/test-proc-pipe.sh | 27 +++++++++++++++++++++++++++
 2 files changed, 42 insertions(+)
 create mode 100755 test/test-proc-pipe.sh
diff mbox series

Patch

diff --git a/pseudo_util.c b/pseudo_util.c
index a94a4da..5f4b356 100644
--- a/pseudo_util.c
+++ b/pseudo_util.c
@@ -620,6 +620,21 @@  pseudo_append_element(char *newpath, char *root, size_t allocated, char **pcurre
 		pseudo_diag("pseudo_append_element: invalid args.\n");
 		return -1;
 	}
+
+	/* If we end up resolving a path into /proc, it has special meaning.
+	 * For instance, /dev/fd/0 -> /proc/self/fd/0 ->
+	 *    /proc/1475524/fd/0 -> /proc/1475524/fd/pipe:[1177004485]
+	 * Trying to access the resolved name "pipe:[....]" may fail.
+	 * Instead, once we enter /proc, we stop expanding symlinks.
+	 *
+	 * This now results in /dev/fd/0 -> /proc/self/fd/0
+	 */
+	if (strncmp(newpath, "/proc", 5) == 0) {
+		pseudo_debug(PDBGF_PATH | PDBGF_VERBOSE, "paes: %s in /proc\n",
+			newpath ? newpath : "<nil>");
+                leave_this = 1;
+	}
+
 	current = *pcurrent;
 	pseudo_debug(PDBGF_PATH | PDBGF_VERBOSE, "pae: '%s', + '%.*s', is_dir %d\n",
 		newpath, (int) elen, element, is_dir);
diff --git a/test/test-proc-pipe.sh b/test/test-proc-pipe.sh
new file mode 100755
index 0000000..30b6880
--- /dev/null
+++ b/test/test-proc-pipe.sh
@@ -0,0 +1,27 @@ 
+#!/bin/bash
+#
+# SPDX-License-Identifier: LGPL-2.1-only
+#
+# See Yocto Project bugzilla 16028
+#
+# It was determined that a utility that use /dev/fd may fail when run under
+# pseudo, while working properly outside.
+#
+# For example: echo "test" | cat /dev/fd/0
+
+# Tests
+result=$(echo "test" | cat 2>&1)
+rc=$?
+if [ $rc -ne 0 -o "$result" != "test" ]; then
+    echo Failed simple echo pipe test - $rc:
+    echo $result
+    exit 1
+fi
+
+result=$(echo "test" | cat /dev/fd/0 2>&1)
+rc=$?
+if [ $rc -ne 0 -o "$result" != "test" ]; then
+    echo Failed /dev/fd/0 echo pipe test - $rc:
+    echo $result
+    exit 1
+fi