Skip to content

Commit b73565a

Browse files
committed
tty: Fix out-of-bound vmalloc access in imageblit
jira LE-3201 cve CVE-2021-47383 Rebuild_History Non-Buildable kernel-rt-4.18.0-553.22.1.rt7.363.el8_10 commit-author Igor Matheus Andrade Torrente <[email protected]> commit 3b0c406 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. Cc: stable <[email protected]> # after 5.15-rc2 is out, give it time to bake Reported-and-tested-by: [email protected] Signed-off-by: Igor Matheus Andrade Torrente <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Greg Kroah-Hartman <[email protected]> (cherry picked from commit 3b0c406) Signed-off-by: Jonathan Maple <[email protected]>
1 parent 1c6e01c commit b73565a

File tree

1 file changed

+19
-2
lines changed

1 file changed

+19
-2
lines changed

drivers/tty/vt/vt.c

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1053,8 +1053,25 @@ static int vc_do_resize(struct tty_struct *tty, struct vc_data *vc,
10531053
new_row_size = new_cols << 1;
10541054
new_screen_size = new_row_size * new_rows;
10551055

1056-
if (new_cols == vc->vc_cols && new_rows == vc->vc_rows)
1057-
return 0;
1056+
if (new_cols == vc->vc_cols && new_rows == vc->vc_rows) {
1057+
/*
1058+
* This function is being called here to cover the case
1059+
* where the userspace calls the FBIOPUT_VSCREENINFO twice,
1060+
* passing the same fb_var_screeninfo containing the fields
1061+
* yres/xres equal to a number non-multiple of vc_font.height
1062+
* and yres_virtual/xres_virtual equal to number lesser than the
1063+
* vc_font.height and yres/xres.
1064+
* In the second call, the struct fb_var_screeninfo isn't
1065+
* being modified by the underlying driver because of the
1066+
* if above, and this causes the fbcon_display->vrows to become
1067+
* negative and it eventually leads to out-of-bound
1068+
* access by the imageblit function.
1069+
* To give the correct values to the struct and to not have
1070+
* to deal with possible errors from the code below, we call
1071+
* the resize_screen here as well.
1072+
*/
1073+
return resize_screen(vc, new_cols, new_rows, user);
1074+
}
10581075

10591076
if (new_screen_size > (4 << 20))
10601077
return -EINVAL;

0 commit comments

Comments
 (0)