Messages in this thread | | | Subject | Re: [PATCH v4] tty: Fix out-of-bound vmalloc access in imageblit | From | Jiri Slaby <> | Date | Fri, 25 Jun 2021 08:09:53 +0200 |
| |
On 24. 06. 21, 22:27, Igor Matheus Andrade Torrente wrote: > This issue happens when a userspace program does an ioctl > FBIOPUT_VSCREENINFO passing the fb_var_screeninfo struct > containing only the fields xres, yres, and bits_per_pixel > with values. > > If this struct is the same as the previous ioctl, the > vc_resize() detects it and doesn't call the resize_screen(), > leaving the fb_var_screeninfo incomplete. And this leads to > the updatescrollmode() calculates a wrong value to > fbcon_display->vrows, which makes the real_y() return a > wrong value of y, and that value, eventually, causes > the imageblit to access an out-of-bound address value. > > To solve this issue I made the resize_screen() be called > even if the screen does not need any resizing, so it will > "fix and fill" the fb_var_screeninfo independently. > > Reported-and-tested-by: syzbot+858dc7a2f7ef07c2c219@syzkaller.appspotmail.com > Signed-off-by: Igor Matheus Andrade Torrente <igormtorrente@gmail.com> > --- > drivers/tty/vt/vt.c | 17 ++++++++++++++++- > 1 file changed, 16 insertions(+), 1 deletion(-) > > diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c > index fa1548d4f94b..e342f5c905bc 100644 > --- a/drivers/tty/vt/vt.c > +++ b/drivers/tty/vt/vt.c > @@ -1220,7 +1220,22 @@ static int vc_do_resize(struct tty_struct *tty, struct vc_data *vc, > new_screen_size = new_row_size * new_rows; > > if (new_cols == vc->vc_cols && new_rows == vc->vc_rows) > - return 0; > + /* This function is being called here to cover the case
This was already commented on v3: <quote> Please do not use networking style comments, use normal ones: /* * This function... </quote>
> + * where the userspace calls the FBIOPUT_VSCREENINFO twice, > + * passing the same fb_var_screeninfo containing the fields: > + * yres/xres equal to a number non-multiple of vc_font.height > + * and yres_virtual/xres_virtual equal to number lesser than the > + * vc_font.height and yres/xres. > + * In the second call, the struct fb_var_screeninfo isn't > + * being modified by the underlying driver because of the > + * if above, and this causes the fbcon_display->vrows to become > + * negative and it eventually leads to out-of-bound > + * access by the imageblit function. > + * To give the correct values to the struct and to not have > + * to deal with possible errors from the code below, we call > + * the resize_screen here as well. > + */ > + return resize_screen(vc, new_cols, new_rows, user);
I suppose you need to add { } after the if given how its body grew.
With what all console drivers have you tested this with?
> > if (new_screen_size > KMALLOC_MAX_SIZE || !new_screen_size) > return -EINVAL; >
-- js suse labs
| |