mirror of
https://github.com/torvalds/linux.git
synced 2026-04-18 06:44:00 -04:00
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:
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user