projects/linux·commit ffbf700d

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

ffbf700d · Linus Torvalds <[email protected]> · 2025-12-01 16:38:21 -08:00

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
Commit
ffbf700df204dd25a48a19979a126e37f5dd1e6a
Parents
d0deeb80 · 922a6f34

Merge commit. Changes below are compared with the first parent: d0deeb80.

Changes

6 files changed · +22 −0

FileStatusAddDelContent
fs/autofs/autofs_i.hmodified+5−0View file
fs/autofs/dev-ioctl.cmodified+1−0View file
fs/autofs/inode.cmodified+1−0View file
fs/autofs/root.cmodified+8−0View file
fs/namespace.cmodified+6−0View file
include/linux/fs.hmodified+1−0View file

fs/autofs/autofs_i.h

View file
diff --git a/fs/autofs/autofs_i.h b/fs/autofs/autofs_i.h
index 23cea74..4fd5555 100644
--- a/fs/autofs/autofs_i.h
+++ b/fs/autofs/autofs_i.h
@@ -16,6 +16,7 @@
#include <linux/wait.h>
#include <linux/sched.h>
#include <linux/sched/signal.h>
+#include <uapi/linux/mount.h>
#include <linux/mount.h>
#include <linux/namei.h>
#include <linux/uaccess.h>
@@ -27,6 +28,9 @@
#include <linux/magic.h>
#include <linux/fs_context.h>
#include <linux/fs_parser.h>
+#include "../mount.h"
+#include <linux/ns_common.h>
+
/* This is the range of ioctl() numbers we claim as ours */
#define AUTOFS_IOC_FIRST AUTOFS_IOC_READY
@@ -114,6 +118,7 @@ struct autofs_sb_info {
int pipefd;
struct file *pipe;
struct pid *oz_pgrp;
+ u64 mnt_ns_id;
int version;
int sub_version;
int min_proto;

fs/autofs/dev-ioctl.c

View file
diff --git a/fs/autofs/dev-ioctl.c b/fs/autofs/dev-ioctl.c
index d8dd150..ed2efe4 100644
--- a/fs/autofs/dev-ioctl.c
+++ b/fs/autofs/dev-ioctl.c
@@ -381,6 +381,7 @@ static int autofs_dev_ioctl_setpipefd(struct file *fp,
swap(sbi->oz_pgrp, new_pid);
sbi->pipefd = pipefd;
sbi->pipe = pipe;
+ sbi->mnt_ns_id = to_ns_common(current->nsproxy->mnt_ns)->ns_id;
sbi->flags &= ~AUTOFS_SBI_CATATONIC;
}
out:

fs/autofs/inode.c

View file
diff --git a/fs/autofs/inode.c b/fs/autofs/inode.c
index f5c16ff..732aee7 100644
--- a/fs/autofs/inode.c
+++ b/fs/autofs/inode.c
@@ -251,6 +251,7 @@ static struct autofs_sb_info *autofs_alloc_sbi(void)
sbi->min_proto = AUTOFS_MIN_PROTO_VERSION;
sbi->max_proto = AUTOFS_MAX_PROTO_VERSION;
sbi->pipefd = -1;
+ sbi->mnt_ns_id = to_ns_common(current->nsproxy->mnt_ns)->ns_id;
set_autofs_type_indirect(&sbi->type);
mutex_init(&sbi->wq_mutex);

fs/autofs/root.c

View file
diff --git a/fs/autofs/root.c b/fs/autofs/root.c
index 174c720..d10df9d 100644
--- a/fs/autofs/root.c
+++ b/fs/autofs/root.c
@@ -341,6 +341,14 @@ static struct vfsmount *autofs_d_automount(struct path *path)
if (autofs_oz_mode(sbi))
return NULL;
+ /* Refuse to trigger mount if current namespace is not the owner
+ * and the mount is propagation private.
+ */
+ if (sbi->mnt_ns_id != to_ns_common(current->nsproxy->mnt_ns)->ns_id) {
+ if (vfsmount_to_propagation_flags(path->mnt) & MS_PRIVATE)
+ return ERR_PTR(-EPERM);
+ }
+
/*
* If an expire request is pending everyone must wait.
* If the expire fails we're still mounted so continue

fs/namespace.c

View file
diff --git a/fs/namespace.c b/fs/namespace.c
index d7afac8..35960fd 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -5148,6 +5148,12 @@ static u64 mnt_to_propagation_flags(struct mount *m)
return propagation;
}
+u64 vfsmount_to_propagation_flags(struct vfsmount *mnt)
+{
+ return mnt_to_propagation_flags(real_mount(mnt));
+}
+EXPORT_SYMBOL_GPL(vfsmount_to_propagation_flags);
+
static void statmount_sb_basic(struct kstatmount *s)
{
struct super_block *sb = s->mnt->mnt_sb;

include/linux/fs.h

View file
diff --git a/include/linux/fs.h b/include/linux/fs.h
index d2cacf9..ce25feb 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2840,6 +2840,7 @@ extern struct file * open_exec(const char *);
/* fs/dcache.c -- generic fs support functions */
extern bool is_subdir(struct dentry *, struct dentry *);
extern bool path_is_under(const struct path *, const struct path *);
+u64 vfsmount_to_propagation_flags(struct vfsmount *mnt);
extern char *file_path(struct file *, char *, int);