Thread (2 messages) 2 messages, 2 authors, 2021-10-25

Re: [OE-core] [pseudo] pseudo_fix_path: do not expand symlinks in /proc

From: Richard Purdie <hidden>
Date: 2021-10-25 18:19:28

On Mon, 2021-10-25 at 14:03 -0400, Sakib Sajal wrote:
quoted hunk ↗ jump to hunk
From: Matt Cowell <redacted>

Some symlinks in /proc, such as those under /proc/[pid]/fd,
/proc/[pid]/cwd, and /proc/[pid]/exe that are not real and should not
have readlink called on them.  These look like symlinks, but behave like
hardlinks.  Readlink does not return actual paths.  Previously
pseudo_fix_path would expand files such as /dev/stdin to paths such as
/proc/6680/fd/pipe:[1270830076] which do not exist.

This issue affects:
- deleted files
- deleted directories
- fifos
- sockets
- anon_inodes (epoll, eventfd, inotify, signalfd, timerfd, etc)

Testing:
- run_tests: all tests passed. Checked the test output to make
             sure the new codepath gets executed.
- perftest: measured time before and after applying the patch
            had insignificant differences (roughly ~1%)
- world build: completed without warning/errors

Signed-off-by: Sakib Sajal <redacted>
---
 pseudo_util.c | 27 +++++++++++++++++++++++++++
 1 file changed, 27 insertions(+)
diff --git a/pseudo_util.c b/pseudo_util.c
index b6980c2..b35a34e 100644
--- a/pseudo_util.c
+++ b/pseudo_util.c
@@ -21,6 +21,8 @@
 #include <sys/time.h>
 #include <unistd.h>
 #include <limits.h>
+#include <sys/vfs.h>
+#include <linux/magic.h>
 
 /* see the comments below about (*real_regcomp)() */
 #include <dlfcn.h>
@@ -29,6 +31,11 @@
 #include "pseudo_ipc.h"
 #include "pseudo_db.h"
 
+/* O_PATH is defined in glibc 2.16 and later only */
+#ifndef O_PATH
+#define O_PATH          010000000
+#endif
+
 struct pseudo_variables {
 	char *key;
 	size_t key_len;
@@ -678,6 +685,26 @@ pseudo_append_element(char *newpath, char *root, size_t allocated, char **pcurre
 	 */
 	if (!leave_this && is_dir) {
 		int is_link = S_ISLNK(buf->st_mode);
+
+		/* do not expand symlinks in the proc filesystem, since they may not be real */
+		if (is_link) {
+			struct statfs sfs;
+			int fd;
+
+			/* statfs follows symlinks, so use fstatfs */
+			fd = open(newpath, O_CLOEXEC | O_PATH | O_NOFOLLOW);
+			if (-1 != fd) {
+				if (0 == fstatfs(fd, &sfs) && sfs.f_type == PROC_SUPER_MAGIC) {
+					pseudo_debug(PDBGF_PATH | PDBGF_VERBOSE,
+						"pae: '%s' is procfs symlink, not expanding\n",
+						newpath);
+					is_link = 0;
+				}
+
+				close(fd);
+			}
+		}
+

Above this code, there is a call:

	if (!pseudo_real_lstat || (pseudo_real_lstat(newpath, buf) == -1)) {

so we do have a statfs structure populated. Can we test buf.f_type ==
PROC_SUPER_MAGIC on that instead of calling open()? Or does that not contain the
right information?

Cheers,

Richard


Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help