mirror of
https://github.com/torvalds/linux.git
synced 2026-05-23 06:31:58 +02:00
fs: add may_copy_tree()
Add a helper that verifies whether a caller may copy a given mount tree. Link: https://lore.kernel.org/r/20250221-brauner-open_tree-v1-5-dbcfcb98c676@kernel.org Signed-off-by: Christian Brauner <brauner@kernel.org>
This commit is contained in:
parent
b73ec10a45
commit
9ed72af4e2
|
|
@ -2808,6 +2808,41 @@ static int do_change_type(struct path *path, int ms_flags)
|
|||
return err;
|
||||
}
|
||||
|
||||
/* may_copy_tree() - check if a mount tree can be copied
|
||||
* @path: path to the mount tree to be copied
|
||||
*
|
||||
* This helper checks if the caller may copy the mount tree starting
|
||||
* from @path->mnt. The caller may copy the mount tree under the
|
||||
* following circumstances:
|
||||
*
|
||||
* (1) The caller is located in the mount namespace of the mount tree.
|
||||
* This also implies that the mount does not belong to an anonymous
|
||||
* mount namespace.
|
||||
* (2) The caller tries to copy an nfs mount referring to a mount
|
||||
* namespace, i.e., the caller is trying to copy a mount namespace
|
||||
* entry from nsfs.
|
||||
* (3) The caller tries to copy a pidfs mount referring to a pidfd.
|
||||
*
|
||||
* Returns true if the mount tree can be copied, false otherwise.
|
||||
*/
|
||||
static inline bool may_copy_tree(struct path *path)
|
||||
{
|
||||
struct mount *mnt = real_mount(path->mnt);
|
||||
const struct dentry_operations *d_op;
|
||||
|
||||
if (check_mnt(mnt))
|
||||
return true;
|
||||
|
||||
d_op = path->dentry->d_op;
|
||||
if (d_op == &ns_dentry_operations)
|
||||
return true;
|
||||
|
||||
if (d_op == &pidfs_dentry_operations)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
static struct mount *__do_loopback(struct path *old_path, int recurse)
|
||||
{
|
||||
struct mount *mnt = ERR_PTR(-EINVAL), *old = real_mount(old_path->mnt);
|
||||
|
|
@ -2815,13 +2850,8 @@ static struct mount *__do_loopback(struct path *old_path, int recurse)
|
|||
if (IS_MNT_UNBINDABLE(old))
|
||||
return mnt;
|
||||
|
||||
if (!check_mnt(old)) {
|
||||
const struct dentry_operations *d_op = old_path->dentry->d_op;
|
||||
|
||||
if (d_op != &ns_dentry_operations &&
|
||||
d_op != &pidfs_dentry_operations)
|
||||
return mnt;
|
||||
}
|
||||
if (!may_copy_tree(old_path))
|
||||
return mnt;
|
||||
|
||||
if (!recurse && has_locked_children(old, old_path->dentry))
|
||||
return mnt;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user