FAILED: patch "[PATCH] fbcon: Avoid OOB font access if console rotation fails" failed to apply to 6.18-stable tree
Subsystems (4)
[email protected]
maintainerThe patch below does not apply to the 6.18-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.18.y
git checkout FETCH_HEAD
git cherry-pick -x e4ef723d8975a2694cc90733a6b888a5e2841842
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026051241-compacted-starless-59c8@gregkh' --subject-prefix 'PATCH 6.18.y' HEAD^..
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From e4ef723d8975a2694cc90733a6b888a5e2841842 Mon Sep 17 00:00:00 2001
From: Thomas Zimmermann <[email protected]>
Date: Tue, 7 Apr 2026 11:23:12 +0200
Subject: [PATCH] fbcon: Avoid OOB font access if console rotation fails
Clear the font buffer if the reallocation during console rotation fails in fbcon_rotate_font(). The putcs implementations for the rotated buffer will return early in this case. See [1] for an example.
Currently, fbcon_rotate_font() keeps the old buffer, which is too small for the rotated font. Printing to the rotated console with a high-enough character code will overflow the font buffer.
v2:
- fix typos in commit message
drivers/video/fbdev/core/fbcon_rotate.c +4 -1
@@ -46,6 +46,10 @@ int fbcon_rotate_font(struct fb_info *info, struct vc_data *vc) info->fbops->fb_sync (info);if (par->fd_size < d_cellsize * len) { +kfree (par->fontbuffer); + par->fontbuffer =NULL ; + par->fd_size =0 ; + dst =kmalloc_array (len, d_cellsize,GFP_KERNEL );if (dst ==NULL ) {
@@ -54,7 +58,6 @@ int fbcon_rotate_font(struct fb_info *info, struct vc_data *vc) } par->fd_size = d_cellsize * len; -kfree (par->fontbuffer); par->fontbuffer = dst; }
Sasha Levin
maintainerPATCH 1/2 fbcon: Rename struct fbcon_ops to struct fbcon_par
From: Thomas Zimmermann <[email protected]>
[ Upstream commit a6adbbc4c32a016146e117b1e9e5242724a75e10 ]
The type struct fbcon_ops contains fbcon state and callbacks. As the callbacks will be removed from struct fbcon_ops, rename the data type to struct fbcon_par. Also rename the variables from ops to par.
The _par postfix ("private access registers") is used throughout the fbdev subsystem for per-driver state. The fbcon pointer within struct fb_info is also named fbcon_par. Hence, the new naming fits existing practice.
v2:
- rename struct fbcon_ops to struct fbcon_par
- fix build for CONFIG_FB_TILEBITTING=n (kernel test robot)
- fix indention
Stable-dep-of: e4ef723d8975 ("fbcon: Avoid OOB font access if console rotation fails")
--- drivers/video/fbdev/core/bitblit.c | 122 +++---- drivers/video/fbdev/core/fbcon.c | 419 ++++++++++++------------ drivers/video/fbdev/core/fbcon.h | 6 +- drivers/video/fbdev/core/fbcon_ccw.c | 146 ++++----- drivers/video/fbdev/core/fbcon_cw.c | 146 ++++----- drivers/video/fbdev/core/fbcon_rotate.c | 40 +-- drivers/video/fbdev/core/fbcon_rotate.h | 6 +- drivers/video/fbdev/core/fbcon_ud.c | 162 ++++----- drivers/video/fbdev/core/softcursor.c | 18 +- drivers/video/fbdev/core/tileblit.c | 28 +- 10 files changed, 541 insertions(+), 552 deletions(-)
drivers/video/fbdev/core/bitblit.c +61 -61
@@ -261,10 +261,10 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info, bool enable, int fg, int bg) {struct fb_cursor cursor; -struct fbcon_ops *ops = info->fbcon_par; +struct fbcon_par *par = info->fbcon_par;unsigned short charmask = vc->vc_hi_font_mask ?0x1ff :0xff ;int w =DIV_ROUND_UP (vc->vc_font.width,8 ), c; -int y =real_y (ops->p, vc->state.y); +int y =real_y (par->p, vc->state.y);int attribute, use_sw = vc->vc_cursor_type &CUR_SW ;int err =1 ;char *src;
@@ -278,10 +278,10 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info, bool enable, attribute =get_attribute (info, c); src = vc->vc_font.data + ((c & charmask) * (w * vc->vc_font.height)); -if (ops->cursor_state.image.data != src || - ops->cursor_reset) { - ops->cursor_state.image.data = src; - cursor.set |=FB_CUR_SETIMAGE ; +if (par->cursor_state.image.data != src || + par->cursor_reset) { + par->cursor_state.image.data = src; + cursor.set |=FB_CUR_SETIMAGE ; }if (attribute) {
@@ -290,46 +290,46 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info, bool enable, dst =kmalloc_array (w, vc->vc_font.height,GFP_ATOMIC );if (!dst)return ; -kfree (ops->cursor_data); - ops->cursor_data = dst; +kfree (par->cursor_data); + par->cursor_data = dst;update_attr (dst, src, attribute, vc); src = dst; } -if (ops->cursor_state.image.fg_color != fg || - ops->cursor_state.image.bg_color != bg || - ops->cursor_reset) { - ops->cursor_state.image.fg_color = fg; - ops->cursor_state.image.bg_color = bg; +if (par->cursor_state.image.fg_color != fg || + par->cursor_state.image.bg_color != bg || + par->cursor_reset) { + par->cursor_state.image.fg_color = fg; + par->cursor_state.image.bg_color = bg; cursor.set |=FB_CUR_SETCMAP ; } -if ((ops->cursor_state.image.dx != (vc->vc_font.width * vc->state.x)) || - (ops->cursor_state.image.dy != (vc->vc_font.height * y)) || - ops->cursor_reset) { - ops->cursor_state.image.dx = vc->vc_font.width * vc->state.x; - ops->cursor_state.image.dy = vc->vc_font.height * y; +if ((par->cursor_state.image.dx != (vc->vc_font.width * vc->state.x)) || + (par->cursor_state.image.dy != (vc->vc_font.height * y)) || + par->cursor_reset) { + par->cursor_state.image.dx = vc->vc_font.width * vc->state.x; + par->cursor_state.image.dy = vc->vc_font.height * y; cursor.set |=FB_CUR_SETPOS ; } -if (ops->cursor_state.image.height != vc->vc_font.height || - ops->cursor_state.image.width != vc->vc_font.width || - ops->cursor_reset) { - ops->cursor_state.image.height = vc->vc_font.height; - ops->cursor_state.image.width = vc->vc_font.width; +if (par->cursor_state.image.height != vc->vc_font.height || + par->cursor_state.image.width != vc->vc_font.width || + par->cursor_reset) { + par->cursor_state.image.height = vc->vc_font.height; + par->cursor_state.image.width = vc->vc_font.width; cursor.set |=FB_CUR_SETSIZE ; } -if (ops->cursor_state.hot.x || ops->cursor_state.hot.y || - ops->cursor_reset) { - ops->cursor_state.hot.x = cursor.hot.y =0 ; +if (par->cursor_state.hot.x || par->cursor_state.hot.y || + par->cursor_reset) { + par->cursor_state.hot.x = cursor.hot.y =0 ; cursor.set |=FB_CUR_SETHOT ; }if (cursor.set &FB_CUR_SETSIZE || - vc->vc_cursor_type != ops->p->cursor_shape || - ops->cursor_state.mask ==NULL || - ops->cursor_reset) { + vc->vc_cursor_type != par->p->cursor_shape || + par->cursor_state.mask ==NULL || + par->cursor_reset) {char *mask =kmalloc_array (w, vc->vc_font.height,GFP_ATOMIC );int cur_height, size, i =0 ;u8 msk =0xff ;
@@ -337,13 +337,13 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info, bool enable,if (!mask)return ; -kfree (ops->cursor_state.mask); - ops->cursor_state.mask = mask; +kfree (par->cursor_state.mask); + par->cursor_state.mask = mask; - ops->p->cursor_shape = vc->vc_cursor_type; + par->p->cursor_shape = vc->vc_cursor_type; cursor.set |=FB_CUR_SETSHAPE ; -switch (CUR_SIZE (ops->p->cursor_shape)) { +switch (CUR_SIZE (par->p->cursor_shape)) {case CUR_NONE : cur_height =0 ;break ;
@@ -372,19 +372,19 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info, bool enable, mask[i++] = msk; } - ops->cursor_state.enable = enable && !use_sw; + par->cursor_state.enable = enable && !use_sw; cursor.image.data = src; - cursor.image.fg_color = ops->cursor_state.image.fg_color; - cursor.image.bg_color = ops->cursor_state.image.bg_color; - cursor.image.dx = ops->cursor_state.image.dx; - cursor.image.dy = ops->cursor_state.image.dy; - cursor.image.height = ops->cursor_state.image.height; - cursor.image.width = ops->cursor_state.image.width; - cursor.hot.x = ops->cursor_state.hot.x; - cursor.hot.y = ops->cursor_state.hot.y; - cursor.mask = ops->cursor_state.mask; - cursor.enable = ops->cursor_state.enable; + cursor.image.fg_color = par->cursor_state.image.fg_color; + cursor.image.bg_color = par->cursor_state.image.bg_color; + cursor.image.dx = par->cursor_state.image.dx; + cursor.image.dy = par->cursor_state.image.dy; + cursor.image.height = par->cursor_state.image.height; + cursor.image.width = par->cursor_state.image.width; + cursor.hot.x = par->cursor_state.hot.x; + cursor.hot.y = par->cursor_state.hot.y; + cursor.mask = par->cursor_state.mask; + cursor.enable = par->cursor_state.enable; cursor.image.depth =1 ; cursor.rop =ROP_XOR ;
@@ -394,31 +394,31 @@ static void bit_cursor(struct vc_data *vc, struct fb_info *info, bool enable,if (err)soft_cursor (info, &cursor); - ops->cursor_reset =0 ; + par->cursor_reset =0 ; }static int bit_update_start (struct fb_info *info) { -struct fbcon_ops *ops = info->fbcon_par; +struct fbcon_par *par = info->fbcon_par;int err; - err =fb_pan_display (info, &ops->var); - ops->var.xoffset = info->var.xoffset; - ops->var.yoffset = info->var.yoffset; - ops->var.vmode = info->var.vmode; + err =fb_pan_display (info, &par->var); + par->var.xoffset = info->var.xoffset; + par->var.yoffset = info->var.yoffset; + par->var.vmode = info->var.vmode;return err; } -void fbcon_set_bitops (struct fbcon_ops *ops) +void fbcon_set_bitops (struct fbcon_par *par) { - ops->bmove = bit_bmove; - ops->clear = bit_clear; - ops->putcs = bit_putcs; - ops->clear_margins = bit_clear_margins; - ops->cursor = bit_cursor; - ops->update_start = bit_update_start; - ops->rotate_font =NULL ; - -if (ops->rotate) -fbcon_set_rotate (ops); + par->bmove = bit_bmove; + par->clear = bit_clear; + par->putcs = bit_putcs; + par->clear_margins = bit_clear_margins; + par->cursor = bit_cursor; + par->update_start = bit_update_start; + par->rotate_font =NULL ; + +if (par->rotate) +fbcon_set_rotate (par); }
drivers/video/fbdev/core/fbcon.c +204 -215
1,061 lines not on this page · raw message
drivers/video/fbdev/core/fbcon.h +3 -3
@@ -50,7 +50,7 @@ struct fbcon_display {const struct fb_videomode *mode; }; -struct fbcon_ops { +struct fbcon_par {void (*bmove)(struct vc_data *vc,struct fb_info *info,int sy,int sx,int dy,int dx,int height,int width); void (*clear)(struct vc_data *vc, struct fb_info *info, int sy,
@@ -185,7 +185,7 @@ static inline u_short fb_scrollmode(struct fbcon_display *fb)#ifdef CONFIG_FB_TILEBLITTING extern void fbcon_set_tileops (struct vc_data *vc,struct fb_info *info);#endif -extern void fbcon_set_bitops (struct fbcon_ops *ops); +extern void fbcon_set_bitops (struct fbcon_par *par);extern int soft_cursor (struct fb_info *info,struct fb_cursor *cursor);#define FBCON_ATTRIBUTE_UNDERLINE 1
@@ -224,7 +224,7 @@ static inline int get_attribute(struct fb_info *info, u16 c) (i == FB_ROTATE_UR || i == FB_ROTATE_UD) ? _r : _v; })#ifdef CONFIG_FRAMEBUFFER_CONSOLE_ROTATION -extern void fbcon_set_rotate (struct fbcon_ops *ops); +extern void fbcon_set_rotate (struct fbcon_par *par);#else #define fbcon_set_rotate (x) do {} while(0)#endif /* CONFIG_FRAMEBUFFER_CONSOLE_ROTATION */
drivers/video/fbdev/core/fbcon_ccw.c +73 -73
261 lines not on this page · raw message
drivers/video/fbdev/core/fbcon_cw.c +73 -73
261 lines not on this page · raw message
drivers/video/fbdev/core/fbcon_rotate.c +20 -20
@@ -20,32 +20,32 @@static int fbcon_rotate_font (struct fb_info *info,struct vc_data *vc) { -struct fbcon_ops *ops = info->fbcon_par; +struct fbcon_par *par = info->fbcon_par;int len, err =0 ;int s_cellsize, d_cellsize, i;const u8 *src;u8 *dst; -if (vc->vc_font.data == ops->fontdata && - ops->p->con_rotate == ops->cur_rotate) +if (vc->vc_font.data == par->fontdata && + par->p->con_rotate == par->cur_rotate) goto finished; - src = ops->fontdata = vc->vc_font.data; - ops->cur_rotate = ops->p->con_rotate; + src = par->fontdata = vc->vc_font.data; + par->cur_rotate = par->p->con_rotate; len = vc->vc_font.charcount; s_cellsize = ((vc->vc_font.width +7 )/8 ) * vc->vc_font.height; d_cellsize = s_cellsize; -if (ops->rotate ==FB_ROTATE_CW || - ops->rotate ==FB_ROTATE_CCW ) +if (par->rotate ==FB_ROTATE_CW || + par->rotate ==FB_ROTATE_CCW ) d_cellsize = ((vc->vc_font.height +7 )/8 ) * vc->vc_font.width;if (info->fbops->fb_sync) info->fbops->fb_sync (info); -if (ops->fd_size < d_cellsize * len) { +if (par->fd_size < d_cellsize * len) { dst =kmalloc_array (len, d_cellsize,GFP_KERNEL );if (dst ==NULL ) {
@@ -53,15 +53,15 @@ static int fbcon_rotate_font(struct fb_info *info, struct vc_data *vc) goto finished; } - ops->fd_size = d_cellsize * len; -kfree (ops->fontbuffer); - ops->fontbuffer = dst; + par->fd_size = d_cellsize * len; +kfree (par->fontbuffer); + par->fontbuffer = dst; } - dst = ops->fontbuffer; -memset (dst,0 , ops->fd_size); + dst = par->fontbuffer; +memset (dst,0 , par->fd_size); -switch (ops->rotate) { +switch (par->rotate) {case FB_ROTATE_UD :for (i = len; i--; ) { rotate_ud(src, dst, vc->vc_font.width,
@@ -93,19 +93,19 @@ static int fbcon_rotate_font(struct fb_info *info, struct vc_data *vc)return err; } -void fbcon_set_rotate (struct fbcon_ops *ops) +void fbcon_set_rotate (struct fbcon_par *par) { - ops->rotate_font = fbcon_rotate_font; + par->rotate_font = fbcon_rotate_font; -switch (ops->rotate) { +switch (par->rotate) {case FB_ROTATE_CW : -fbcon_rotate_cw (ops); +fbcon_rotate_cw (par);break ;case FB_ROTATE_UD : -fbcon_rotate_ud (ops); +fbcon_rotate_ud (par);break ;case FB_ROTATE_CCW : -fbcon_rotate_ccw (ops); +fbcon_rotate_ccw (par);break ; } }
drivers/video/fbdev/core/fbcon_rotate.h +3 -3
@@ -90,7 +90,7 @@ static inline void rotate_ccw(const char *in, char *out, u32 width, u32 height) } } -extern void fbcon_rotate_cw (struct fbcon_ops *ops); -extern void fbcon_rotate_ud (struct fbcon_ops *ops); -extern void fbcon_rotate_ccw (struct fbcon_ops *ops); +extern void fbcon_rotate_cw (struct fbcon_par *par); +extern void fbcon_rotate_ud (struct fbcon_par *par); +extern void fbcon_rotate_ccw (struct fbcon_par *par);#endif
drivers/video/fbdev/core/fbcon_ud.c +81 -81
291 lines not on this page · raw message
drivers/video/fbdev/core/softcursor.c +9 -9
@@ -21,7 +21,7 @@int soft_cursor (struct fb_info *info,struct fb_cursor *cursor) { -struct fbcon_ops *ops = info->fbcon_par; +struct fbcon_par *par = info->fbcon_par;unsigned int scan_align = info->pixmap.scan_align -1 ;unsigned int buf_align = info->pixmap.buf_align -1 ;unsigned int i, size, dsize, s_pitch, d_pitch;
@@ -34,19 +34,19 @@ int soft_cursor(struct fb_info *info, struct fb_cursor *cursor) s_pitch = (cursor->image.width +7 ) >>3 ; dsize = s_pitch * cursor->image.height; -if (dsize +sizeof (struct fb_image ) != ops->cursor_size) { -kfree (ops->cursor_src); - ops->cursor_size = dsize +sizeof (struct fb_image ); +if (dsize +sizeof (struct fb_image ) != par->cursor_size) { +kfree (par->cursor_src); + par->cursor_size = dsize +sizeof (struct fb_image ); - ops->cursor_src =kmalloc (ops->cursor_size,GFP_ATOMIC ); -if (!ops->cursor_src) { - ops->cursor_size =0 ; + par->cursor_src =kmalloc (par->cursor_size,GFP_ATOMIC ); +if (!par->cursor_src) { + par->cursor_size =0 ;return -ENOMEM ; } } - src = ops->cursor_src +sizeof (struct fb_image ); - image = (struct fb_image *)ops->cursor_src; + src = par->cursor_src +sizeof (struct fb_image ); + image = (struct fb_image *)par->cursor_src; *image = cursor->image; d_pitch = (s_pitch + scan_align) & ~scan_align;
drivers/video/fbdev/core/tileblit.c +14 -14
@@ -151,34 +151,34 @@ static void tile_cursor(struct vc_data *vc, struct fb_info *info, bool enable,static int tile_update_start (struct fb_info *info) { -struct fbcon_ops *ops = info->fbcon_par; +struct fbcon_par *par = info->fbcon_par;int err; - err =fb_pan_display (info, &ops->var); - ops->var.xoffset = info->var.xoffset; - ops->var.yoffset = info->var.yoffset; - ops->var.vmode = info->var.vmode; + err =fb_pan_display (info, &par->var); + par->var.xoffset = info->var.xoffset; + par->var.yoffset = info->var.yoffset; + par->var.vmode = info->var.vmode;return err; }void fbcon_set_tileops (struct vc_data *vc,struct fb_info *info) {struct fb_tilemap map; -struct fbcon_ops *ops = info->fbcon_par; +struct fbcon_par *par = info->fbcon_par; - ops->bmove = tile_bmove; - ops->clear = tile_clear; - ops->putcs = tile_putcs; - ops->clear_margins = tile_clear_margins; - ops->cursor = tile_cursor; - ops->update_start = tile_update_start; + par->bmove = tile_bmove; + par->clear = tile_clear; + par->putcs = tile_putcs; + par->clear_margins = tile_clear_margins; + par->cursor = tile_cursor; + par->update_start = tile_update_start; -if (ops->p) { +if (par->p) { map.width = vc->vc_font.width; map.height = vc->vc_font.height; map.depth =1 ; map.length = vc->vc_font.charcount; - map.data = ops->p->fontdata; + map.data = par->p->fontdata; info->tileops->fb_settile (info, &map); } }
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 2/2 fbcon: Avoid OOB font access if console rotation fails
From: Thomas Zimmermann <[email protected]>
[ Upstream commit e4ef723d8975a2694cc90733a6b888a5e2841842 ]
Clear the font buffer if the reallocation during console rotation fails in fbcon_rotate_font(). The putcs implementations for the rotated buffer will return early in this case. See [1] for an example.
Currently, fbcon_rotate_font() keeps the old buffer, which is too small for the rotated font. Printing to the rotated console with a high-enough character code will overflow the font buffer.
v2:
- fix typos in commit message
--- drivers/video/fbdev/core/fbcon_rotate.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/video/fbdev/core/fbcon_rotate.c +4 -1
@@ -46,6 +46,10 @@ static int fbcon_rotate_font(struct fb_info *info, struct vc_data *vc) info->fbops->fb_sync (info);if (par->fd_size < d_cellsize * len) { +kfree (par->fontbuffer); + par->fontbuffer =NULL ; + par->fd_size =0 ; + dst =kmalloc_array (len, d_cellsize,GFP_KERNEL );if (dst ==NULL ) {
@@ -54,7 +58,6 @@ static int fbcon_rotate_font(struct fb_info *info, struct vc_data *vc) } par->fd_size = d_cellsize * len; -kfree (par->fontbuffer); par->fontbuffer = dst; }
Signature · 1 line
2.53.0