[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <20200507170242.6cbb88ae672deed67152e221@linux-foundation.org>
Date: Thu, 7 May 2020 17:02:42 -0700
From: Andrew Morton <akpm@...ux-foundation.org>
To: Vasily Averin <vvs@...tuozzo.com>
Cc: linux-kernel@...r.kernel.org, Waiman Long <longman@...hat.com>,
Andreas Schwab <schwab@...e.de>,
Matthew Wilcox <willy@...radead.org>
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@...tuozzo.com> wrote:
> new_pos should jump through hole of unused ids,
> pos can be updated inside "for" cycle.
>
> Cc: stable@...r.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;
}
Powered by blists - more mailing lists