From 0f327ce9b2dcfdd3b95fa3e57c0dd7b2ae38b07e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hubert=20Figui=C3=A8re?= Date: Sat, 11 Nov 2023 11:33:02 -0500 Subject: [PATCH] xdg-document-portal: Honour O_NOFOLLOW on open MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Resolve the symlink from /proc before opening See https://github.com/flatpak/xdg-desktop-portal/issues/1117 Signed-off-by: Hubert Figuière --- document-portal/document-portal-fuse.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/document-portal/document-portal-fuse.c b/document-portal/document-portal-fuse.c index 842a317e4..6aa7a0a1a 100644 --- a/document-portal/document-portal-fuse.c +++ b/document-portal/document-portal-fuse.c @@ -1,5 +1,6 @@ /* * Copyright © 2018 Red Hat, Inc + * Copyright © 2023 GNOME Foundation Inc. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -16,6 +17,7 @@ * * Authors: * Alexander Larsson + * Hubert Figuière */ #include "config.h" @@ -1897,7 +1899,26 @@ xdp_fuse_open (fuse_req_t req, return; path = fd_to_path (inode->physical->fd); - fd = open (path, open_flags, 0); + if (open_flags & O_NOFOLLOW) + { + ssize_t res; + char actual_path[PATH_MAX]; + /* + * `path` is a path to the fd entry in `/proc`, which is a symlink + * to the actual file. Opening it directly with `O_NOFOLLOW` will + * fail. So we should resolve it first then we can honour the no + * follow flag. + */ + res = readlink (path, actual_path, sizeof (actual_path)); + if (res == sizeof (actual_path)) + return xdp_reply_err (op, req, ENAMETOOLONG); + if (res < 0) + return xdp_reply_err (op, req, errno); + + fd = open (actual_path, open_flags, 0); + } + else + fd = open (path, open_flags, 0); if (fd == -1) return xdp_reply_err (op, req, errno);