[1/2] pseudo: do not expand symlinks in /proc

Submitted by Richard Purdie on Oct. 7, 2020, 4:20 p.m. | Patch ID: 177037

Details

Message ID 20201007162018.3187947-1-richard.purdie@linuxfoundation.org
State Master Next
Commit d194fe839fdde6d44eef5ee3b66b8de9c46a89e6
Headers show

Commit Message

Richard Purdie Oct. 7, 2020, 4:20 p.m.
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:
timed builds before and after applying patch, without significant
measurable difference.
$ bitbake -c compile <image>; time bitbake <image>

installed pseudo on an image and was unable to reproduce the test
on bug report after applying the patch.

[YOCTO #13288]

Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
---
 meta/recipes-devtools/pseudo/files/proc.patch | 86 +++++++++++++++++++
 meta/recipes-devtools/pseudo/pseudo_git.bb    |  1 +
 2 files changed, 87 insertions(+)
 create mode 100644 meta/recipes-devtools/pseudo/files/proc.patch

Patch hide | download patch | download mbox

diff --git a/meta/recipes-devtools/pseudo/files/proc.patch b/meta/recipes-devtools/pseudo/files/proc.patch
new file mode 100644
index 00000000000..57ae9bf9504
--- /dev/null
+++ b/meta/recipes-devtools/pseudo/files/proc.patch
@@ -0,0 +1,86 @@ 
+From: Matt Cowell <matt.cowell@nokia.com>
+From: "Sakib Sajal" <sakib.sajal@windriver.com>
+
+pseudo: do not expand symlinks in /proc
+
+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:
+timed builds before and after applying patch, without significant
+measurable difference.
+$ bitbake -c compile <image>; time bitbake <image>
+
+installed pseudo on an image and was unable to reproduce the test
+on bug report after applying the patch.
+
+[YOCTO #13288]
+
+Signed-off-by: Sakib Sajal <sakib.sajal@windriver.com>
+---
+ pseudo_util.c | 27 +++++++++++++++++++++++++++
+ 1 file changed, 27 insertions(+)
+
+diff --git a/pseudo_util.c b/pseudo_util.c
+index c867ed6..bce4d1e 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;
+@@ -677,6 +684,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);
++			}
++		}
++
+ 		if (link_recursion >= PSEUDO_MAX_LINK_RECURSION && is_link) {
+ 			pseudo_diag("link recursion too deep, not expanding path '%s'.\n", newpath);
+ 			is_link = 0;
diff --git a/meta/recipes-devtools/pseudo/pseudo_git.bb b/meta/recipes-devtools/pseudo/pseudo_git.bb
index bc20a2f134e..90f5cb0bcf2 100644
--- a/meta/recipes-devtools/pseudo/pseudo_git.bb
+++ b/meta/recipes-devtools/pseudo/pseudo_git.bb
@@ -9,6 +9,7 @@  SRC_URI = "git://git.yoctoproject.org/pseudo;branch=oe-core \
            file://xattr_fix.patch \
            file://mayunlink.patch \
            file://pathfix.patch \
+           file://proc.patch \
            file://fallback-passwd \
            file://fallback-group \
            "