[Bug 216073] [s390x] kernel BUG at mm/usercopy.c:101! usercopy: Kernel memory exposure attempt detected from vmalloc 'n o area' (offset 0, size 1)!

bugzilla-daemon
2022-06-12T20:54:00Z

--- Comment #19 from yuzhao@google.com ---
On Sun, Jun 12, 2022 at 1:52 PM Matthew Wilcox <willy@infradead.org> wrote:
>
> On Sun, Jun 12, 2022 at 12:43:45PM -0600, Yu Zhao wrote:
> > On Sun, Jun 12, 2022 at 12:05 PM Matthew Wilcox <willy@infradead.org>
> wrote:
> > >
> > > On Sun, Jun 12, 2022 at 11:59:58AM -0600, Yu Zhao wrote:
> > > > Please let me know if there is something we want to test -- I can
> > > > reproduce the problem reliably:
> > > >
> > > > ------------[ cut here ]------------
> > > > kernel BUG at mm/usercopy.c:101!
> > >
> > > The line right before cut here would have been nice ;-)
> >
> > Right.
> >
> > $ grep usercopy:
> > usercopy: Kernel memory exposure attempt detected from vmalloc (offset
> > 2882303761517129920, size 11)!
> > usercopy: Kernel memory exposure attempt detected from vmalloc (offset
> > 8574853690513436864, size 11)!
> > usercopy: Kernel memory exposure attempt detected from vmalloc (offset
> > 7998392938210013376, size 11)!
>
> That's a different problem. And, er, what? How on earth do we have
> an offset that big?!
>
> struct vm_struct *area = find_vm_area(ptr);
> offset = ptr - area->addr;
> if (offset + n > get_vm_area_size(area))
> usercopy_abort("vmalloc", NULL, to_user, offset, n);
>
> That first offset is 0x2800'0000'0000'30C0
>
> You said it was easy to replicate; can you add:
>
> printk("addr:%px ptr:%px\n", area->addr, ptr);
>
> so that we can start to understand how we end up with such a bogus
> offset?

Here you go:

addr:96ffffdfebcd4000 ptr:ffffffdfebcd70c0
usercopy: Kernel memory exposure attempt detected from vmalloc (offset
7566047373982445760, size 11)!

And, not sure if it'd be helpful, with the vmap:

va_start:ffffffd83db0d000 va_end:ffffffd83db13000
addr:44ffffd83db0d000 ptr:ffffffd83db100c0
usercopy: Kernel memory exposure attempt detected from vmalloc (offset
13474770085092536512, size 11)!

which seems to explain why the fix worked.

+ if (offset + n > get_vm_area_size(area)) {
+ struct vmap_area *vmap =
find_vmap_area((unsigned long)ptr);
+
+ if (vmap)
+ printk("va_start:%px va_end:%px\n",
vmap->va_start, vmap->va_end);
+ printk("addr:%px ptr:%px\n", area->addr, ptr);
usercopy_abort("vmalloc", NULL, to_user, offset, n);
+ }