namespace: fix proc mount iteration

The m->index isn't updated when m->show() overflows and retains its
value before the current mount causing a restart to start at the same
value. If that happens in short order to due a quickly expanding mount
table this would cause the same mount to be shown again and again.

Ensure that *pos always equals the mount id of the mount that was
returned by start/next. On restart after overflow mnt_find_id_at(*pos)
finds the exact mount. This should avoid duplicates, avoid skips and
should handle concurrent modification just fine.

Cc: <stable@vger.kernel.org>
Fixed: 2eea9ce431 ("mounts: keep list of mounts in an rbtree")
Link: https://patch.msgid.link/20260129-geleckt-treuhand-4bb940acacd9@brauner
Signed-off-by: Christian Brauner <brauner@kernel.org>
This commit is contained in:
Christian Brauner
2026-01-29 14:52:22 +01:00
parent a41dbf5e00
commit 4a403d7aa9

View File

@@ -1531,23 +1531,33 @@ static struct mount *mnt_find_id_at_reverse(struct mnt_namespace *ns, u64 mnt_id
static void *m_start(struct seq_file *m, loff_t *pos)
{
struct proc_mounts *p = m->private;
struct mount *mnt;
down_read(&namespace_sem);
return mnt_find_id_at(p->ns, *pos);
mnt = mnt_find_id_at(p->ns, *pos);
if (mnt)
*pos = mnt->mnt_id_unique;
return mnt;
}
static void *m_next(struct seq_file *m, void *v, loff_t *pos)
{
struct mount *next = NULL, *mnt = v;
struct mount *mnt = v;
struct rb_node *node = rb_next(&mnt->mnt_node);
++*pos;
if (node) {
next = node_to_mount(node);
struct mount *next = node_to_mount(node);
*pos = next->mnt_id_unique;
return next;
}
return next;
/*
* No more mounts. Set pos past current mount's ID so that if
* iteration restarts, mnt_find_id_at() returns NULL.
*/
*pos = mnt->mnt_id_unique + 1;
return NULL;
}
static void m_stop(struct seq_file *m, void *v)