All of lore.kernel.org
 help / color / mirror / Atom feed
From: Mark Hatle <mark.hatle@kernel.crashing.org>
To: yocto-patches@lists.yoctoproject.org
Cc: seebs@seebs.net, richard.purdie@linuxfoundation.org
Subject: [pseudo][PATCH 11/20] pseudo_util.c: Skip realpath like expansion for /proc on Linux
Date: Thu, 15 Jan 2026 17:43:27 -0600	[thread overview]
Message-ID: <1768520616-7289-12-git-send-email-mark.hatle@kernel.crashing.org> (raw)
In-Reply-To: <1768520616-7289-1-git-send-email-mark.hatle@kernel.crashing.org>

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 check link targets until it finds one that
does not resolve.  It stops at that points.  This ensures that special /proc
behavior can be maintained.

In the /proc filesystem, on Linux, paths can be opened even if they can't
be stated.  The 'pipe' appears to be one of these special files, so using
lstat to check if it can be opened is an easy way to determine if we have
stumbled onto one of these special files.

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 | 68 +++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 68 insertions(+)

diff --git a/pseudo_util.c b/pseudo_util.c
index a94a4da..d16b14c 100644
--- a/pseudo_util.c
+++ b/pseudo_util.c
@@ -614,12 +614,40 @@ pseudo_append_element(char *newpath, char *root, size_t allocated, char **pcurre
 	size_t curlen;
 	int is_dir = S_ISDIR(buf->st_mode);
 	char *current;
+#ifdef PSEUDO_PORT_LINUX
+	int is_proc = 0;
+	char *proc_path = NULL;
+#endif
 	if (!newpath ||
 	    !pcurrent || !*pcurrent ||
 	    !root || !element) {
 		pseudo_diag("pseudo_append_element: invalid args.\n");
 		return -1;
 	}
+
+#ifdef PSEUDO_PORT_LINUX
+	/* 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.
+	 *
+	 * We verify each link target and only expand if it exists.
+	 */
+	if (strncmp(newpath, "/proc/", 6) == 0) {
+		pseudo_debug(PDBGF_PATH | PDBGF_VERBOSE, "paes: %s in /proc\n",
+			newpath ? newpath : "<nil>");
+		/* Store off the path for later */
+		proc_path = strdup(newpath);
+		/* If memory can't be allocated for newpath,
+		 * fall through and do standard processing
+		 */
+		if (!proc_path)
+			pseudo_diag("allocation failed seeking memory for path (%s).\n", newpath);
+		else
+			is_proc = 1;
+	}
+#endif
+
 	current = *pcurrent;
 	pseudo_debug(PDBGF_PATH | PDBGF_VERBOSE, "pae: '%s', + '%.*s', is_dir %d\n",
 		newpath, (int) elen, element, is_dir);
@@ -700,6 +728,33 @@ pseudo_append_element(char *newpath, char *root, size_t allocated, char **pcurre
 			if (*linkbuf == '/') {
 				current = root;
 			} else {
+#ifdef PSEUDO_PORT_LINUX
+				if (is_proc) {
+					/* Check that the link target exists, otherwise stop resolving since /proc is special! */
+					PSEUDO_STATBUF statbuf;
+
+					size_t target_link_max = pseudo_path_max();
+					char *target_link_path = malloc(pseudo_path_max());
+
+					if (!target_link_path)
+						pseudo_diag("allocation failed seeking memory for path (%s/%s).\n", proc_path, linkbuf);
+						/* Fall through, nothing we can do here */
+					else {
+						snprintf(target_link_path, target_link_max, "%s/%s", proc_path, linkbuf);
+
+						if (!pseudo_real_lstat || (pseudo_real_lstat(target_link_path, &statbuf) == -1)) {
+							pseudo_debug(PDBGF_PATH, "proc link (%s) target (%s) does not exist, skipping.\n", newpath, target_link_path);
+							free(target_link_path);
+							free(proc_path);
+							*pcurrent = current;
+							return 1;
+						} else
+							pseudo_debug(PDBGF_PATH, "proc link (%s) target (%s) exists.\n", newpath, target_link_path);
+
+						free(target_link_path);
+					}
+				}
+#endif
 				/* point back at the end of the previous path... */
 				current -= (elen + 1);
 			}
@@ -716,13 +771,26 @@ pseudo_append_element(char *newpath, char *root, size_t allocated, char **pcurre
 			++link_recursion;
 			retval = pseudo_append_elements(newpath, root, allocated, pcurrent, linkbuf, linklen, 0, buf);
 			--link_recursion;
+
+#ifdef PSEUDO_PORT_LINUX
+			if (is_proc)
+				free(proc_path);
+#endif
+
 			return retval;
 		}
 	}
+
 	/* we used to always append a slash here. now we don't; append_elements
 	 * handles slashes, so just update the pointer.
 	 */
 	*pcurrent = current;
+
+#ifdef PSEUDO_PORT_LINUX
+	/* We must not have used this to get here... */
+	if (is_proc)
+		free(proc_path);
+#endif
 	return 1;
 }
 
-- 
2.43.0



  parent reply	other threads:[~2026-01-15 23:43 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-01-15 23:43 [pseudo][PATCH 00/20] Consolidated pseudo patches Mark Hatle
2026-01-15 23:43 ` [pseudo][PATCH 01/20] test-syscall: Remove build warning Mark Hatle
2026-01-15 23:43 ` [pseudo][PATCH 02/20] test: Cleanup test output Mark Hatle
2026-01-15 23:43 ` [pseudo][PATCH 03/20] test/test-statx.sh: It should be a failure if pseudo prints an error Mark Hatle
2026-01-15 23:43 ` [pseudo][PATCH 04/20] test-realpath: Verify the realpath behavior matches glibc Mark Hatle
2026-01-15 23:43 ` [pseudo][PATCH 05/20] run_tests.sh: In verbose mode, include pseudo.log in output Mark Hatle
2026-01-15 23:43 ` [pseudo][PATCH 06/20] test/test-statx: Add uutils test case Mark Hatle
2026-01-15 23:43 ` [pseudo][PATCH 07/20] test/test-nftw: Avoid compile warnings Mark Hatle
2026-01-15 23:43 ` [pseudo][PATCH 08/20] test-tclsh-fork: Skip test if tclsh is not available Mark Hatle
2026-01-15 23:43 ` [pseudo][PATCH 09/20] ports/unix/guts/realpath.c: realpath fails if the resolved path doesn't exist Mark Hatle
2026-01-15 23:43 ` [pseudo][PATCH 10/20] test/test-proc-pipe.sh: Add test case for proc pipes Mark Hatle
2026-01-15 23:43 ` Mark Hatle [this message]
2026-01-15 23:43 ` [pseudo][PATCH 12/20] ports/unix/guts/realpath.c: Fix indents Mark Hatle
2026-01-15 23:43 ` [pseudo][PATCH 13/20] ports/linux/pseudo_wrappers.c: Reorder the syscall operations Mark Hatle
2026-01-15 23:43 ` [pseudo][PATCH 14/20] ports/linux/pseudo_wrappers.c: Call the wrappers where possible Mark Hatle
2026-01-15 23:43 ` [pseudo][PATCH 15/20] ports/linux: Add additional EFAULTS for Linux functions Mark Hatle
2026-01-15 23:43 ` [pseudo][PATCH 16/20] Update COPYRIGHT files Mark Hatle
2026-01-15 23:43 ` [pseudo][PATCH 17/20] makewrappers: improve error handling and robustness Mark Hatle
2026-01-15 23:43 ` [pseudo][PATCH 18/20] pseudo: code quality scan - resolved various potential issues Mark Hatle
2026-01-15 23:43 ` [pseudo][PATCH 19/20] configure: Minor code quality changes Mark Hatle
2026-01-15 23:43 ` [pseudo][PATCH 20/20] Makefile.in: Bump version to 1.9.3 Mark Hatle
     [not found] ` <188B0C23901378A4.2703508@lists.yoctoproject.org>
2026-01-17 16:08   ` [yocto-patches] [pseudo][PATCH 13/20] ports/linux/pseudo_wrappers.c: Reorder the syscall operations Mark Hatle
     [not found] ` <188B0C2348C47D4E.2703508@lists.yoctoproject.org>
2026-01-17 16:10   ` [yocto-patches] [pseudo][PATCH 15/20] ports/linux: Add additional EFAULTS for Linux functions 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=1768520616-7289-12-git-send-email-mark.hatle@kernel.crashing.org \
    --to=mark.hatle@kernel.crashing.org \
    --cc=richard.purdie@linuxfoundation.org \
    --cc=seebs@seebs.net \
    --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.