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

Merge tag 'vfs-6.19-rc1.autofs' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs

Pull autofs update from Christian Brauner:
"Prevent futile mount triggers in private mount namespaces.

Fix a problematic loop in autofs when a mount namespace contains
autofs mounts that are propagation private and there is no
namespace-specific automount daemon to handle possible automounting.

Previously, attempted path resolution would loop until MAXSYMLINKS was
reached before failing, causing significant noise in the log.

The fix adds a check in autofs ->d_automount() so that the VFS can
immediately return EPERM in this case. Since the mount is propagation
private, EPERM is the most appropriate error code"

* tag 'vfs-6.19-rc1.autofs' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs:
autofs: dont trigger mount if it cant succeed

+22
+5
fs/autofs/autofs_i.h
··· 16 16 #include <linux/wait.h> 17 17 #include <linux/sched.h> 18 18 #include <linux/sched/signal.h> 19 + #include <uapi/linux/mount.h> 19 20 #include <linux/mount.h> 20 21 #include <linux/namei.h> 21 22 #include <linux/uaccess.h> ··· 28 27 #include <linux/magic.h> 29 28 #include <linux/fs_context.h> 30 29 #include <linux/fs_parser.h> 30 + #include "../mount.h" 31 + #include <linux/ns_common.h> 32 + 31 33 32 34 /* This is the range of ioctl() numbers we claim as ours */ 33 35 #define AUTOFS_IOC_FIRST AUTOFS_IOC_READY ··· 118 114 int pipefd; 119 115 struct file *pipe; 120 116 struct pid *oz_pgrp; 117 + u64 mnt_ns_id; 121 118 int version; 122 119 int sub_version; 123 120 int min_proto;
+1
fs/autofs/dev-ioctl.c
··· 381 381 swap(sbi->oz_pgrp, new_pid); 382 382 sbi->pipefd = pipefd; 383 383 sbi->pipe = pipe; 384 + sbi->mnt_ns_id = to_ns_common(current->nsproxy->mnt_ns)->ns_id; 384 385 sbi->flags &= ~AUTOFS_SBI_CATATONIC; 385 386 } 386 387 out:
+1
fs/autofs/inode.c
··· 251 251 sbi->min_proto = AUTOFS_MIN_PROTO_VERSION; 252 252 sbi->max_proto = AUTOFS_MAX_PROTO_VERSION; 253 253 sbi->pipefd = -1; 254 + sbi->mnt_ns_id = to_ns_common(current->nsproxy->mnt_ns)->ns_id; 254 255 255 256 set_autofs_type_indirect(&sbi->type); 256 257 mutex_init(&sbi->wq_mutex);
+8
fs/autofs/root.c
··· 341 341 if (autofs_oz_mode(sbi)) 342 342 return NULL; 343 343 344 + /* Refuse to trigger mount if current namespace is not the owner 345 + * and the mount is propagation private. 346 + */ 347 + if (sbi->mnt_ns_id != to_ns_common(current->nsproxy->mnt_ns)->ns_id) { 348 + if (vfsmount_to_propagation_flags(path->mnt) & MS_PRIVATE) 349 + return ERR_PTR(-EPERM); 350 + } 351 + 344 352 /* 345 353 * If an expire request is pending everyone must wait. 346 354 * If the expire fails we're still mounted so continue
+6
fs/namespace.c
··· 5148 5148 return propagation; 5149 5149 } 5150 5150 5151 + u64 vfsmount_to_propagation_flags(struct vfsmount *mnt) 5152 + { 5153 + return mnt_to_propagation_flags(real_mount(mnt)); 5154 + } 5155 + EXPORT_SYMBOL_GPL(vfsmount_to_propagation_flags); 5156 + 5151 5157 static void statmount_sb_basic(struct kstatmount *s) 5152 5158 { 5153 5159 struct super_block *sb = s->mnt->mnt_sb;
+1
include/linux/fs.h
··· 2840 2840 /* fs/dcache.c -- generic fs support functions */ 2841 2841 extern bool is_subdir(struct dentry *, struct dentry *); 2842 2842 extern bool path_is_under(const struct path *, const struct path *); 2843 + u64 vfsmount_to_propagation_flags(struct vfsmount *mnt); 2843 2844 2844 2845 extern char *file_path(struct file *, char *, int); 2845 2846