Re: [PATCH v2] vt: don't use kmalloc() for the unicode screen buffer

From: Daniel Vetter
Date: Tue Mar 31 2020 - 04:43:26 EST


On Mon, Mar 30, 2020 at 9:08 PM Sam Ravnborg <sam@xxxxxxxxxxxx> wrote:
>
> Hi Nicolas
>
> On Sat, Mar 28, 2020 at 10:25:11PM -0400, Nicolas Pitre wrote:
> > Even if the actual screen size is bounded in vc_do_resize(), the unicode
> > buffer is still a little more than twice the size of the glyph buffer
> > and may exceed MAX_ORDER down the kmalloc() path. This can be triggered
> > from user space.
> >
> > Since there is no point having a physically contiguous buffer here,
> > let's avoid the above issue as well as reducing pressure on high order
> > allocations by using vmalloc() instead.
> >
> > Signed-off-by: Nicolas Pitre <nico@xxxxxxxxxxx>
> > Cc: <stable@xxxxxxxxxxxxxxx>
> >
> > ---
> >
> > Changes since v1:
> >
> > - Added missing include, found by kbuild test robot.
> > Strange that my own build doesn't complain.
>
> When I did the drmP.h removal vmalloc was one of the header files
> that turned up missing in many cases - but only for some architectures.
> I learned to include alpha in the build.
> If it survived building for alpha then I had fixed the majority
> of the issues related to random inherited includes.
>
> The patch itself looks good.
>
> Acked-by: Sam Ravnborg <sam@xxxxxxxxxxxx>

Greg, I'm assuming you'll pick this up through the tty tree? I kinda
want to stop the habit of merging vt patches, maybe then
get_maintainers will stop thinking I'm responsible somehow :-)
-Daniel

>
> >
> > diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
> > index 15d2769805..d9eb5661e9 100644
> > --- a/drivers/tty/vt/vt.c
> > +++ b/drivers/tty/vt/vt.c
> > @@ -81,6 +81,7 @@
> > #include <linux/errno.h>
> > #include <linux/kd.h>
> > #include <linux/slab.h>
> > +#include <linux/vmalloc.h>
> > #include <linux/major.h>
> > #include <linux/mm.h>
> > #include <linux/console.h>
> > @@ -350,7 +351,7 @@ static struct uni_screen *vc_uniscr_alloc(unsigned int cols, unsigned int rows)
> > /* allocate everything in one go */
> > memsize = cols * rows * sizeof(char32_t);
> > memsize += rows * sizeof(char32_t *);
> > - p = kmalloc(memsize, GFP_KERNEL);
> > + p = vmalloc(memsize);
> > if (!p)
> > return NULL;
> >
> > @@ -366,7 +367,7 @@ static struct uni_screen *vc_uniscr_alloc(unsigned int cols, unsigned int rows)
> >
> > static void vc_uniscr_set(struct vc_data *vc, struct uni_screen *new_uniscr)
> > {
> > - kfree(vc->vc_uni_screen);
> > + vfree(vc->vc_uni_screen);
> > vc->vc_uni_screen = new_uniscr;
> > }
> >



--
Daniel Vetter
Software Engineer, Intel Corporation
+41 (0) 79 365 57 48 - http://blog.ffwll.ch