fbdev: fbcon: Fix KASAN slab-out-of-bounds read in rotated font buffer
Subsystems (3)
PATCH 1/1 fbdev: fbcon: Fix KASAN slab-out-of-bounds read in rotated font buffer
The root cause of this KASAN slab-out-of-bounds read is that fbcon fails to reallocate the rotated font buffer (par->rotated.buf) when the font character count changes but the font dimensions (width and height) remain the same.
When a user changes the font via ioctl(KDFONTOP), fbcon_do_set_font() is called. If the user first sets a 256-character font, enables rotation, and then sets a 512-character font with the exact same width and height, resize evaluates to false. The function then directly calls update_screen(vc). Notice that fbcon_do_set_font() never calls par->bitops->rotate_font() to update the rotated font buffer for the new font. As a result, par->rotated.buf remains sized for the old 256-character font.
When update_screen(vc) is called, it eventually reaches cw_putcs_aligned(), which attempts to read the glyphs from the rotated buffer. Since vc->vc_font.charcount is now 512, vc->vc_hi_font_mask is set, making charmask equal to 0x1ff (511). If the text buffer contains a character with an index >= 256, src will point out of bounds of the old par->rotated.buf (which only holds 256 glyphs). The subsequent read in __fb_pad_aligned_buffer() triggers the KASAN slab-out-of-bounds crash.
To fix this, fbcon_do_set_font() must call par->bitops->rotate_font() to update the rotated font buffer before calling vc_resize() or update_screen(). If vc_resize() fails and the old font is restored in the error path, rotate_font() must be called again to restore the rotated buffer.
This pattern of updating the rotated font buffer was previously established in fbcon_modechanged() by commit ef7656e85f1a ("fbdev: Fix out-of-bounds access when rotating console after font resize"). The fix applies this exact idiom to fbcon_do_set_font(). By placing it before vc_resize() and update_screen(), we ensure the buffer is correctly sized before any rendering occurs. Checking con_is_visible(vc) is also correct here, as hidden consoles will have their rotation state updated later via fbcon_switch() when they become visible.
Furthermore, by calling rotate_font() again in the err_out path, we ensure that if vc_resize() fails, the rotated buffer is restored to match the old vc->vc_font. Without this, restoring a 512-character font to a 256-character font on failure would leave the rotated buffer sized for 512 characters, which wastes memory; or worse, restoring a 256-character font to a 512-character font would leave the buffer too small, causing an out-of-bounds read later.
--- drivers/video/fbdev/core/fbcon.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)
drivers/video/fbdev/core/fbcon.c +14 -0
@@ -2432,6 +2432,13 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h, int charcount,else if (!vc->vc_hi_font_mask && charcount ==512 )set_vc_hi_font (vc, true); +if (con_is_visible (vc)) { +if (par->bitops->rotate_font && par->bitops->rotate_font (info, vc)) { + par->rotate =FB_ROTATE_UR ; +set_blitting_type (vc, info); + } + } +if (resize) {int cols, rows;
@@ -2466,6 +2473,13 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h, int charcount,else if (!old_hi_font_mask && vc->vc_hi_font_mask)set_vc_hi_font (vc, false); +if (con_is_visible (vc)) { +if (par->bitops->rotate_font && par->bitops->rotate_font (info, vc)) { + par->rotate =FB_ROTATE_UR ; +set_blitting_type (vc, info); + } + } +font_data_put (data);return ret;
Signature · 1 line
2.43.0
Hi,
I wanted to follow up on this patch, if anyone has had a chance to review it.
Thanks,
Tayyab
Quoted 90 lines · Syed Tayyab Farooq
The root cause of this KASAN slab-out-of-bounds read is that fbcon fails to reallocate the rotated font buffer (
par->rotated.buf) when the font character count changes but the font dimensions (width and height) remain the same.When a user changes the font via ioctl(KDFONTOP),
fbcon_do_set_font()is called. If the user first sets a 256-character font, enables rotation, and then sets a 512-character font with the exact same width and height, resize evaluates to false. The function then directly callsupdate_screen(vc). Notice thatfbcon_do_set_font()never callspar->bitops->rotate_font()to update the rotated font buffer for the new font. As a result,par->rotated.bufremains sized for the old 256-character font.When
update_screen(vc)is called, it eventually reachescw_putcs_aligned(), which attempts to read the glyphs from the rotated buffer. Sincevc->vc_font.charcountis now 512,vc->vc_hi_font_maskis set, making charmask equal to0x1ff(511). If the text buffer contains a character with an index >= 256, src will point out of bounds of the oldpar->rotated.buf(which only holds 256 glyphs). The subsequent read in__fb_pad_aligned_buffer()triggers the KASAN slab-out-of-bounds crash.To fix this,
fbcon_do_set_font()must callpar->bitops->rotate_font()to update the rotated font buffer before callingvc_resize()orupdate_screen(). Ifvc_resize()fails and the old font is restored in the error path,rotate_font()must be called again to restore the rotated buffer.This pattern of updating the rotated font buffer was previously established in
fbcon_modechanged()by commitef7656e85f1a("fbdev: Fix out-of-bounds access when rotating console after font resize"). The fix applies this exact idiom tofbcon_do_set_font(). By placing it beforevc_resize()andupdate_screen(), we ensure the buffer is correctly sized before any rendering occurs. Checkingcon_is_visible(vc)is also correct here, as hidden consoles will have their rotation state updated later viafbcon_switch()when they become visible.Furthermore, by calling
rotate_font()again in theerr_outpath, we ensure that ifvc_resize()fails, the rotated buffer is restored to match the oldvc->vc_font. Without this, restoring a 512-character font to a 256-character font on failure would leave the rotated buffer sized for 512 characters, which wastes memory; or worse, restoring a 256-character font to a 512-character font would leave the buffer too small, causing an out-of-bounds read later.Fixes e4fc27618b75 ("[PATCH] fbcon: Console Rotation - Prepare fbcon for console rotation")Assisted-by Gemini:gemini-3.6-flash Gemini:gemini-3.1-pro-preview syzbotReported-by [email protected]Signed-off-by Syed Tayyab Farooq <[email protected]>--- drivers/video/fbdev/core/fbcon.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+)drivers/video/fbdev/core/fbcon.c +14
-1@@ -2432,6 +2432,13 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h, int charcount,else if (!vc->vc_hi_font_mask && charcount ==512 )set_vc_hi_font (vc, true); +if (con_is_visible (vc)) { +if (par->bitops->rotate_font && par->bitops->rotate_font (info, vc)) { + par->rotate =FB_ROTATE_UR ; +set_blitting_type (vc, info); + } + } +if (resize) {int cols, rows;@@ -2466,6 +2473,13 @@ static int fbcon_do_set_font(struct vc_data *vc, int w, int h, int charcount,else if (!old_hi_font_mask && vc->vc_hi_font_mask)set_vc_hi_font (vc, false); +if (con_is_visible (vc)) { +if (par->bitops->rotate_font && par->bitops->rotate_font (info, vc)) { + par->rotate =FB_ROTATE_UR ; +set_blitting_type (vc, info); + } + } +font_data_put (data);return ret; --2.43.0