[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <aSnFME6-LqQXKazB@casper.infradead.org>
Date: Fri, 28 Nov 2025 15:52:16 +0000
From: Matthew Wilcox <willy@...radead.org>
To: "Sokolowski, Jan" <jan.sokolowski@...el.com>
Cc: Christian König <christian.koenig@....com>,
"linux-kernel@...r.kernel.org" <linux-kernel@...r.kernel.org>,
Andrew Morton <akpm@...ux-foundation.org>,
"linux-fsdevel@...r.kernel.org" <linux-fsdevel@...r.kernel.org>,
"linux-mm@...ck.org" <linux-mm@...ck.org>
Subject: Re: [RFC PATCH 1/1] idr: do not create idr if new id would be
outside given range
On Fri, Nov 28, 2025 at 09:03:08AM +0000, Sokolowski, Jan wrote:
> So, shall I send a V2 of that patch and add you as co-developer there?
No. You didn't co-develop anything. You reported the bug, badly.
What I'm trying to do right now is figure out what the syzbot report
actually was. In all the DRM specialness, you've lost the original
information, so I can't add the original syzbot links. All I can find
is https://gitlab.freedesktop.org/drm/xe/kernel/-/issues/6449
which doesn't link to a syzbot report, so that's a dead end.
> Regards
> Jan
>
> > -----Original Message-----
> > From: Matthew Wilcox <willy@...radead.org>
> > Sent: Thursday, November 27, 2025 3:55 PM
> > To: Christian König <christian.koenig@....com>
> > Cc: Sokolowski, Jan <jan.sokolowski@...el.com>; linux-
> > kernel@...r.kernel.org; Andrew Morton <akpm@...ux-foundation.org>;
> > linux-fsdevel@...r.kernel.org; linux-mm@...ck.org
> > Subject: Re: [RFC PATCH 1/1] idr: do not create idr if new id would be outside
> > given range
> >
> > On Thu, Nov 27, 2025 at 02:11:02PM +0000, Matthew Wilcox wrote:
> > > Hm. That's not what it does for me. It gives me id == 1, which isn't
> > > correct! I'll look into that, but it'd be helpful to know what
> > > combination of inputs gives us 2.
> >
> > Oh, never mind, I see what's happening.
> >
> > int idr_alloc(struct idr *idr, void *ptr, int start, int end, gfp_t gfp)
> >
> > ret = idr_alloc_u32(idr, ptr, &id, end > 0 ? end - 1 : INT_MAX, gfp);
> > so it's passing 0 as 'max' to idr_alloc_u32() which does:
> >
> > slot = idr_get_free(&idr->idr_rt, &iter, gfp, max - base);
> >
> > and max - base becomes -1 or rather ULONG_MAX, and so we'll literally
> > allocate any number. If the first slot is full, we'll get back 1
> > and then add 'base' to it, giving 2.
> >
> > Here's the new test-case:
> >
> > +void idr_alloc2_test(void)
> > +{
> > + int id;
> > + struct idr idr = IDR_INIT_BASE(idr, 1);
> > +
> > + id = idr_alloc(&idr, idr_alloc2_test, 0, 1, GFP_KERNEL);
> > + assert(id == -ENOSPC);
> > +
> > + id = idr_alloc(&idr, idr_alloc2_test, 1, 2, GFP_KERNEL);
> > + assert(id == 1);
> > +
> > + id = idr_alloc(&idr, idr_alloc2_test, 0, 1, GFP_KERNEL);
> > + assert(id == -ENOSPC);
> > +
> > + id = idr_alloc(&idr, idr_alloc2_test, 0, 2, GFP_KERNEL);
> > + assert(id == -ENOSPC);
> > +
> > + idr_destroy(&idr);
> > +}
> >
> > and with this patch, it passes:
> >
> > +++ b/lib/idr.c
> > @@ -40,6 +40,8 @@ int idr_alloc_u32(struct idr *idr, void *ptr, u32 *nextid,
> >
> > if (WARN_ON_ONCE(!(idr->idr_rt.xa_flags & ROOT_IS_IDR)))
> > idr->idr_rt.xa_flags |= IDR_RT_MARKER;
> > + if (max < base)
> > + return -ENOSPC;
> >
> > id = (id < base) ? 0 : id - base;
> > radix_tree_iter_init(&iter, id);
>
Powered by blists - more mailing lists