Messages in this thread | | | Date | Thu, 7 May 2020 17:02:42 -0700 | From | Andrew Morton <> | Subject | Re: [PATCH] ipc/util.c: sysvipc_find_ipc() incorrectly updates position index |
| |
On Wed, 6 May 2020 09:25:54 +0300 Vasily Averin <vvs@virtuozzo.com> wrote:
> new_pos should jump through hole of unused ids, > pos can be updated inside "for" cycle. > > Cc: stable@vger.kernel.org > Fixes: 89163f93c6f9 ("ipc/util.c: sysvipc_find_ipc() should increase position index")
This:
> --- a/ipc/util.c > +++ b/ipc/util.c > @@ -764,21 +764,21 @@ static struct kern_ipc_perm *sysvipc_find_ipc(struct ipc_ids *ids, loff_t pos, > total++; > } > > - *new_pos = pos + 1; > + ipc = NULL; > if (total >= ids->in_use) > - return NULL; > + goto out; > > for (; pos < ipc_mni; pos++) { > ipc = idr_find(&ids->ipcs_idr, pos); > if (ipc != NULL) { > rcu_read_lock(); > ipc_lock_object(ipc); > - return ipc; > + break; > } > } > - > - /* Out of range - return NULL to terminate iteration */ > - return NULL; > +out: > + *new_pos = pos + 1; > + return ipc; > } > > static void *sysvipc_proc_next(struct seq_file *s, void *it, loff_t *pos)
Messes up Matthew's "ipc: convert ipcs_idr to XArray" (http://lkml.kernel.org/r/20200326151418.27545-1-willy@infradead.org).
Here's how I resolved things. Please check?
static struct kern_ipc_perm *sysvipc_find_ipc(struct ipc_ids *ids, loff_t pos, loff_t *new_pos) { unsigned long index = pos; struct kern_ipc_perm *ipc;
rcu_read_lock(); ipc = xa_find(&ids->ipcs, &index, ULONG_MAX, XA_PRESENT); if (ipc) ipc_lock_object(ipc); else rcu_read_unlock(); *new_pos = pos + 1; return ipc; }
| |