From 4cea033ae58d553174e9439c41579e33b6515d50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Almeida?= Date: Tue, 29 Apr 2025 15:38:50 -0300 Subject: [PATCH 1/3] ovl: Fix nested backing file paths MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ANBZ: #33963 commit 924577e4f6ca473de1528953a0e13505fae61d7b upstream. commit ec5f0b44125c0c7d8f472b34ac7a61a6cf12e246 6.12.y stable. When the lowerdir of an overlayfs is a merged directory of another overlayfs, ovl_open_realfile() will fail to open the real file and point to a lower dentry copy, without the proper parent path. After this, d_path() will then display the path incorrectly as if the file is placed in the root directory. This bug can be triggered with the following setup: mkdir -p ovl-A/lower ovl-A/upper ovl-A/merge ovl-A/work mkdir -p ovl-B/upper ovl-B/merge ovl-B/work cp /bin/cat ovl-A/lower/ mount -t overlay overlay -o \ lowerdir=ovl-A/lower,upperdir=ovl-A/upper,workdir=ovl-A/work \ ovl-A/merge mount -t overlay overlay -o \ lowerdir=ovl-A/merge,upperdir=ovl-B/upper,workdir=ovl-B/work \ ovl-B/merge ovl-A/merge/cat /proc/self/maps | grep --color cat ovl-B/merge/cat /proc/self/maps | grep --color cat The first cat will correctly show `/ovl-A/merge/cat`, while the second one shows just `/cat`. To fix that, uses file_user_path() inside of backing_file_open() to get the correct file path for the dentry. Co-developed-by: John Schoenick Signed-off-by: John Schoenick Signed-off-by: André Almeida Fixes: def3ae83da02 ("fs: store real path instead of fake path in backing file f_path") Cc: # v6.7 Signed-off-by: Miklos Szeredi Signed-off-by: Greg Kroah-Hartman --- fs/overlayfs/file.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fs/overlayfs/file.c b/fs/overlayfs/file.c index 112f41498aec..a937f790d397 100644 --- a/fs/overlayfs/file.c +++ b/fs/overlayfs/file.c @@ -60,8 +60,8 @@ static struct file *ovl_open_realfile(const struct file *file, if (!inode_owner_or_capable(real_idmap, realinode)) flags &= ~O_NOATIME; - realfile = backing_file_open(&file->f_path, flags, realpath, - current_cred()); + realfile = backing_file_open(file_user_path((struct file *) file), + flags, realpath, current_cred()); } revert_creds(old_cred); -- Gitee From 7b527c375865d1f3d38cbb25752999987f4c50a8 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Mon, 4 Aug 2025 22:11:28 +1000 Subject: [PATCH 2/3] ovl: use I_MUTEX_PARENT when locking parent in ovl_create_temp() ANBZ: #33963 commit 5f1c8965e748c150d580a2ea8fbee1bd80d07a24 upstream. commit 9c4afcaf8275a04cf0d41a9aa1f340457d6e91aa 6.12.y stable. ovl_create_temp() treats "workdir" as a parent in which it creates an object so it should use I_MUTEX_PARENT. Prior to the commit identified below the lock was taken by the caller which sometimes used I_MUTEX_PARENT and sometimes used I_MUTEX_NORMAL. The use of I_MUTEX_NORMAL was incorrect but unfortunately copied into ovl_create_temp(). Note to backporters: This patch only applies after the last Fixes given below (post v6.16). To fix the bug in v6.7 and later the inode_lock() call in ovl_copy_up_workdir() needs to nest using I_MUTEX_PARENT. Link: https://lore.kernel.org/all/67a72070.050a0220.3d72c.0022.GAE@google.com/ Cc: stable@vger.kernel.org Reported-by: syzbot+7836a68852a10ec3d790@syzkaller.appspotmail.com Tested-by: syzbot+7836a68852a10ec3d790@syzkaller.appspotmail.com Fixes: c63e56a4a652 ("ovl: do not open/llseek lower file with upper sb_writers held") Fixes: d2c995581c7c ("ovl: Call ovl_create_temp() without lock held.") Signed-off-by: NeilBrown Signed-off-by: Amir Goldstein Signed-off-by: Greg Kroah-Hartman --- fs/overlayfs/copy_up.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fs/overlayfs/copy_up.c b/fs/overlayfs/copy_up.c index 881178d4c099..9f16a3813d8a 100644 --- a/fs/overlayfs/copy_up.c +++ b/fs/overlayfs/copy_up.c @@ -758,7 +758,7 @@ static int ovl_copy_up_workdir(struct ovl_copy_up_ctx *c) return err; ovl_start_write(c->dentry); - inode_lock(wdir); + inode_lock_nested(wdir, I_MUTEX_PARENT); temp = ovl_create_temp(ofs, c->workdir, &cattr); inode_unlock(wdir); ovl_end_write(c->dentry); -- Gitee From 7146efc4611852d8a10a01912c55b441d9259d57 Mon Sep 17 00:00:00 2001 From: Adrian Hunter Date: Mon, 13 Oct 2025 10:22:43 +0300 Subject: [PATCH 3/3] perf/core: Fix MMAP event path names with backing files ANBZ: #33963 commit 8818f507a9391019a3ec7c57b1a32e4b386e48a5 upstream. commit 7024b11fb47e29909cf2f3d2e6931f9b8c42de4f 6.12.y stable. Some file systems like FUSE-based ones or overlayfs may record the backing file in struct vm_area_struct vm_file, instead of the user file that the user mmapped. Since commit def3ae83da02f ("fs: store real path instead of fake path in backing file f_path"), file_path() no longer returns the user file path when applied to a backing file. There is an existing helper file_user_path() for that situation. Use file_user_path() instead of file_path() to get the path for MMAP and MMAP2 events. Example: Setup: # cd /root # mkdir test ; cd test ; mkdir lower upper work merged # cp `which cat` lower # mount -t overlay overlay -olowerdir=lower,upperdir=upper,workdir=work merged # perf record -e intel_pt//u -- /root/test/merged/cat /proc/self/maps ... 55b0ba399000-55b0ba434000 r-xp 00018000 00:1a 3419 /root/test/merged/cat ... [ perf record: Woken up 1 times to write data ] [ perf record: Captured and wrote 0.060 MB perf.data ] # Before: File name is wrong (/cat), so decoding fails: # perf script --no-itrace --show-mmap-events cat 367 [016] 100.491492: PERF_RECORD_MMAP2 367/367: [0x55b0ba399000(0x9b000) @ 0x18000 00:02 3419 489959280]: r-xp /cat ... # perf script --itrace=e | wc -l Warning: 19 instruction trace errors 19 # After: File name is correct (/root/test/merged/cat), so decoding is ok: # perf script --no-itrace --show-mmap-events cat 364 [016] 72.153006: PERF_RECORD_MMAP2 364/364: [0x55ce4003d000(0x9b000) @ 0x18000 00:02 3419 3132534314]: r-xp /root/test/merged/cat # perf script --itrace=e # perf script --itrace=e | wc -l 0 # Fixes: def3ae83da02f ("fs: store real path instead of fake path in backing file f_path") Signed-off-by: Adrian Hunter Signed-off-by: Peter Zijlstra (Intel) Acked-by: Amir Goldstein Cc: stable@vger.kernel.org Signed-off-by: Greg Kroah-Hartman --- kernel/events/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/events/core.c b/kernel/events/core.c index 7bb2c6cbb3ce..387d2805df47 100644 --- a/kernel/events/core.c +++ b/kernel/events/core.c @@ -8859,7 +8859,7 @@ static void perf_event_mmap_event(struct perf_mmap_event *mmap_event) * need to add enough zero bytes after the string to handle * the 64bit alignment we do later. */ - name = file_path(file, buf, PATH_MAX - sizeof(u64)); + name = d_path(file_user_path(file), buf, PATH_MAX - sizeof(u64)); if (IS_ERR(name)) { name = "//toolong"; goto cpy_name; -- Gitee