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

Configure Feed

Select the types of activity you want to include in your feed.

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: 2eea9ce4310d8 ("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>

+15 -5
+15 -5
fs/namespace.c
··· 1531 1531 static void *m_start(struct seq_file *m, loff_t *pos) 1532 1532 { 1533 1533 struct proc_mounts *p = m->private; 1534 + struct mount *mnt; 1534 1535 1535 1536 down_read(&namespace_sem); 1536 1537 1537 - return mnt_find_id_at(p->ns, *pos); 1538 + mnt = mnt_find_id_at(p->ns, *pos); 1539 + if (mnt) 1540 + *pos = mnt->mnt_id_unique; 1541 + return mnt; 1538 1542 } 1539 1543 1540 1544 static void *m_next(struct seq_file *m, void *v, loff_t *pos) 1541 1545 { 1542 - struct mount *next = NULL, *mnt = v; 1546 + struct mount *mnt = v; 1543 1547 struct rb_node *node = rb_next(&mnt->mnt_node); 1544 1548 1545 - ++*pos; 1546 1549 if (node) { 1547 - next = node_to_mount(node); 1550 + struct mount *next = node_to_mount(node); 1548 1551 *pos = next->mnt_id_unique; 1552 + return next; 1549 1553 } 1550 - return next; 1554 + 1555 + /* 1556 + * No more mounts. Set pos past current mount's ID so that if 1557 + * iteration restarts, mnt_find_id_at() returns NULL. 1558 + */ 1559 + *pos = mnt->mnt_id_unique + 1; 1560 + return NULL; 1551 1561 } 1552 1562 1553 1563 static void m_stop(struct seq_file *m, void *v)