2020-03-28 22:18:07

by Nicolas Pitre

[permalink] [raw]
Subject: [PATCH] vt: don't use kmalloc() for the unicode screen buffer

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 <[email protected]>
Cc: <[email protected]>

diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 15d2769805..7c10edb648 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -350,7 +350,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 +366,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;
}


2020-03-28 23:37:29

by kernel test robot

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

Hi Nicolas,

I love your patch! Yet something to improve:

[auto build test ERROR on tty/tty-testing]
[also build test ERROR on v5.6-rc7 next-20200327]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]

url: https://github.com/0day-ci/linux/commits/Nicolas-Pitre/vt-don-t-use-kmalloc-for-the-unicode-screen-buffer/20200329-060123
base: https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git tty-testing
config: mips-fuloong2e_defconfig (attached as .config)
compiler: mips64el-linux-gcc (GCC) 5.5.0
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
GCC_VERSION=5.5.0 make.cross ARCH=mips

If you fix the issue, kindly add following tag
Reported-by: kbuild test robot <[email protected]>

All error/warnings (new ones prefixed by >>):

drivers/tty/vt/vt.c: In function 'vc_uniscr_alloc':
>> drivers/tty/vt/vt.c:353:6: error: implicit declaration of function 'vmalloc' [-Werror=implicit-function-declaration]
p = vmalloc(memsize);
^
>> drivers/tty/vt/vt.c:353:4: warning: assignment makes pointer from integer without a cast [-Wint-conversion]
p = vmalloc(memsize);
^
drivers/tty/vt/vt.c: In function 'vc_uniscr_set':
>> drivers/tty/vt/vt.c:369:2: error: implicit declaration of function 'vfree' [-Werror=implicit-function-declaration]
vfree(vc->vc_uni_screen);
^
cc1: some warnings being treated as errors

vim +/vmalloc +353 drivers/tty/vt/vt.c

343
344 static struct uni_screen *vc_uniscr_alloc(unsigned int cols, unsigned int rows)
345 {
346 struct uni_screen *uniscr;
347 void *p;
348 unsigned int memsize, i;
349
350 /* allocate everything in one go */
351 memsize = cols * rows * sizeof(char32_t);
352 memsize += rows * sizeof(char32_t *);
> 353 p = vmalloc(memsize);
354 if (!p)
355 return NULL;
356
357 /* initial line pointers */
358 uniscr = p;
359 p = uniscr->lines + rows;
360 for (i = 0; i < rows; i++) {
361 uniscr->lines[i] = p;
362 p += cols * sizeof(char32_t);
363 }
364 return uniscr;
365 }
366
367 static void vc_uniscr_set(struct vc_data *vc, struct uni_screen *new_uniscr)
368 {
> 369 vfree(vc->vc_uni_screen);
370 vc->vc_uni_screen = new_uniscr;
371 }
372

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/[email protected]


Attachments:
(No filename) (2.72 kB)
.config.gz (18.74 kB)
Download all attachments

2020-03-29 00:14:32

by kernel test robot

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

Hi Nicolas,

I love your patch! Yet something to improve:

[auto build test ERROR on tty/tty-testing]
[also build test ERROR on v5.6-rc7 next-20200327]
[if your patch is applied to the wrong git tree, please drop us a note to help
improve the system. BTW, we also suggest to use '--base' option to specify the
base tree in git format-patch, please see https://stackoverflow.com/a/37406982]

url: https://github.com/0day-ci/linux/commits/Nicolas-Pitre/vt-don-t-use-kmalloc-for-the-unicode-screen-buffer/20200329-060123
base: https://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty.git tty-testing
config: mips-nlm_xlp_defconfig (attached as .config)
compiler: mips64-linux-gcc (GCC) 9.2.0
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
GCC_VERSION=9.2.0 make.cross ARCH=mips

If you fix the issue, kindly add following tag
Reported-by: kbuild test robot <[email protected]>

All error/warnings (new ones prefixed by >>):

drivers/tty/vt/vt.c: In function 'vc_uniscr_alloc':
>> drivers/tty/vt/vt.c:353:6: error: implicit declaration of function 'vmalloc'; did you mean 'kvmalloc'? [-Werror=implicit-function-declaration]
353 | p = vmalloc(memsize);
| ^~~~~~~
| kvmalloc
>> drivers/tty/vt/vt.c:353:4: warning: assignment to 'void *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
353 | p = vmalloc(memsize);
| ^
drivers/tty/vt/vt.c: In function 'vc_uniscr_set':
>> drivers/tty/vt/vt.c:369:2: error: implicit declaration of function 'vfree'; did you mean 'kvfree'? [-Werror=implicit-function-declaration]
369 | vfree(vc->vc_uni_screen);
| ^~~~~
| kvfree
cc1: some warnings being treated as errors

vim +353 drivers/tty/vt/vt.c

343
344 static struct uni_screen *vc_uniscr_alloc(unsigned int cols, unsigned int rows)
345 {
346 struct uni_screen *uniscr;
347 void *p;
348 unsigned int memsize, i;
349
350 /* allocate everything in one go */
351 memsize = cols * rows * sizeof(char32_t);
352 memsize += rows * sizeof(char32_t *);
> 353 p = vmalloc(memsize);
354 if (!p)
355 return NULL;
356
357 /* initial line pointers */
358 uniscr = p;
359 p = uniscr->lines + rows;
360 for (i = 0; i < rows; i++) {
361 uniscr->lines[i] = p;
362 p += cols * sizeof(char32_t);
363 }
364 return uniscr;
365 }
366
367 static void vc_uniscr_set(struct vc_data *vc, struct uni_screen *new_uniscr)
368 {
> 369 vfree(vc->vc_uni_screen);
370 vc->vc_uni_screen = new_uniscr;
371 }
372

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/[email protected]


Attachments:
(No filename) (2.87 kB)
.config.gz (21.00 kB)
Download all attachments

2020-03-29 02:28:55

by Nicolas Pitre

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

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 <[email protected]>
Cc: <[email protected]>

---

Changes since v1:

- Added missing include, found by kbuild test robot.
Strange that my own build doesn't complain.

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;
}

2020-03-30 19:10:39

by Sam Ravnborg

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

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 <[email protected]>
> Cc: <[email protected]>
>
> ---
>
> 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 <[email protected]>

>
> 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;
> }
>

2020-03-31 08:46:03

by Daniel Vetter

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

On Mon, Mar 30, 2020 at 9:08 PM Sam Ravnborg <[email protected]> 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 <[email protected]>
> > Cc: <[email protected]>
> >
> > ---
> >
> > 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 <[email protected]>

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

2020-03-31 10:42:34

by Greg Kroah-Hartman

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

On Tue, Mar 31, 2020 at 10:43:11AM +0200, Daniel Vetter wrote:
> On Mon, Mar 30, 2020 at 9:08 PM Sam Ravnborg <[email protected]> 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 <[email protected]>
> > > Cc: <[email protected]>
> > >
> > > ---
> > >
> > > 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 <[email protected]>
>
> 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 :-)

Yes, I'll take it, and have been taking vt patches for a few releases
now so don't worry, you aren't responsible anymore :)

thanks,

greg k-h