Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge patch series "vfs: if RESOLVE_NO_XDEV passed to openat2, don't *trigger* automounts"

Askar Safin <safinaskar@zohomail.com> says:

openat2 had a bug: if we pass RESOLVE_NO_XDEV, then openat2
doesn't traverse through automounts, but may still trigger them.
See this link for full bug report with reproducer:
https://lore.kernel.org/linux-fsdevel/20250817075252.4137628-1-safinaskar@zohomail.com/

This patchset fixes the bug.

RESOLVE_NO_XDEV logic hopefully becomes more clear:
now we immediately fail when we cross mountpoints.

* patches from https://lore.kernel.org/20250825181233.2464822-1-safinaskar@zohomail.com:
openat2: don't trigger automounts with RESOLVE_NO_XDEV
namei: move cross-device check to __traverse_mounts
namei: remove LOOKUP_NO_XDEV check from handle_mounts
namei: move cross-device check to traverse_mounts

Link: https://lore.kernel.org/20250825181233.2464822-1-safinaskar@zohomail.com
Signed-off-by: Christian Brauner <brauner@kernel.org>

+14 -6
+14 -6
fs/namei.c
··· 1449 1449 dentry->d_inode) 1450 1450 return -EISDIR; 1451 1451 1452 + /* No need to trigger automounts if mountpoint crossing is disabled. */ 1453 + if (lookup_flags & LOOKUP_NO_XDEV) 1454 + return -EXDEV; 1455 + 1452 1456 if (count && (*count)++ >= MAXSYMLINKS) 1453 1457 return -ELOOP; 1454 1458 ··· 1476 1472 /* Allow the filesystem to manage the transit without i_rwsem 1477 1473 * being held. */ 1478 1474 if (flags & DCACHE_MANAGE_TRANSIT) { 1475 + if (lookup_flags & LOOKUP_NO_XDEV) { 1476 + ret = -EXDEV; 1477 + break; 1478 + } 1479 1479 ret = path->dentry->d_op->d_manage(path, false); 1480 1480 flags = smp_load_acquire(&path->dentry->d_flags); 1481 1481 if (ret < 0) ··· 1497 1489 // here we know it's positive 1498 1490 flags = path->dentry->d_flags; 1499 1491 need_mntput = true; 1492 + if (unlikely(lookup_flags & LOOKUP_NO_XDEV)) { 1493 + ret = -EXDEV; 1494 + break; 1495 + } 1500 1496 continue; 1501 1497 } 1502 1498 } ··· 1642 1630 return -ECHILD; 1643 1631 } 1644 1632 ret = traverse_mounts(path, &jumped, &nd->total_link_count, nd->flags); 1645 - if (jumped) { 1646 - if (unlikely(nd->flags & LOOKUP_NO_XDEV)) 1647 - ret = -EXDEV; 1648 - else 1649 - nd->state |= ND_JUMPED; 1650 - } 1633 + if (jumped) 1634 + nd->state |= ND_JUMPED; 1651 1635 if (unlikely(ret)) { 1652 1636 dput(path->dentry); 1653 1637 if (path->mnt != nd->path.mnt)