Skip to content

Commit e64242c

Browse files
committed
fbcon: Prevent that screen size is smaller than font size
We need to prevent that users configure a screen size which is smaller than the currently selected font size. Otherwise rendering chars on the screen will access memory outside the graphics memory region. This patch adds a new function fbcon_modechange_possible() which implements this check and which later may be extended with other checks if necessary. The new function is called from the FBIOPUT_VSCREENINFO ioctl handler in fbmem.c, which will return -EINVAL if userspace asked for a too small screen size. Signed-off-by: Helge Deller <[email protected]> Reviewed-by: Geert Uytterhoeven <[email protected]> Cc: [email protected] # v5.4+
1 parent 65a01e6 commit e64242c

File tree

3 files changed

+35
-1
lines changed

3 files changed

+35
-1
lines changed

drivers/video/fbdev/core/fbcon.c

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2736,6 +2736,34 @@ void fbcon_update_vcs(struct fb_info *info, bool all)
27362736
}
27372737
EXPORT_SYMBOL(fbcon_update_vcs);
27382738

2739+
/* let fbcon check if it supports a new screen resolution */
2740+
int fbcon_modechange_possible(struct fb_info *info, struct fb_var_screeninfo *var)
2741+
{
2742+
struct fbcon_ops *ops = info->fbcon_par;
2743+
struct vc_data *vc;
2744+
unsigned int i;
2745+
2746+
WARN_CONSOLE_UNLOCKED();
2747+
2748+
if (!ops)
2749+
return 0;
2750+
2751+
/* prevent setting a screen size which is smaller than font size */
2752+
for (i = first_fb_vc; i <= last_fb_vc; i++) {
2753+
vc = vc_cons[i].d;
2754+
if (!vc || vc->vc_mode != KD_TEXT ||
2755+
registered_fb[con2fb_map[i]] != info)
2756+
continue;
2757+
2758+
if (vc->vc_font.width > FBCON_SWAP(var->rotate, var->xres, var->yres) ||
2759+
vc->vc_font.height > FBCON_SWAP(var->rotate, var->yres, var->xres))
2760+
return -EINVAL;
2761+
}
2762+
2763+
return 0;
2764+
}
2765+
EXPORT_SYMBOL_GPL(fbcon_modechange_possible);
2766+
27392767
int fbcon_mode_deleted(struct fb_info *info,
27402768
struct fb_videomode *mode)
27412769
{

drivers/video/fbdev/core/fbmem.c

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1107,7 +1107,9 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd,
11071107
return -EFAULT;
11081108
console_lock();
11091109
lock_fb_info(info);
1110-
ret = fb_set_var(info, &var);
1110+
ret = fbcon_modechange_possible(info, &var);
1111+
if (!ret)
1112+
ret = fb_set_var(info, &var);
11111113
if (!ret)
11121114
fbcon_update_vcs(info, var.activate & FB_ACTIVATE_ALL);
11131115
unlock_fb_info(info);

include/linux/fbcon.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ void fbcon_new_modelist(struct fb_info *info);
1515
void fbcon_get_requirement(struct fb_info *info,
1616
struct fb_blit_caps *caps);
1717
void fbcon_fb_blanked(struct fb_info *info, int blank);
18+
int fbcon_modechange_possible(struct fb_info *info,
19+
struct fb_var_screeninfo *var);
1820
void fbcon_update_vcs(struct fb_info *info, bool all);
1921
void fbcon_remap_all(struct fb_info *info);
2022
int fbcon_set_con2fb_map_ioctl(void __user *argp);
@@ -33,6 +35,8 @@ static inline void fbcon_new_modelist(struct fb_info *info) {}
3335
static inline void fbcon_get_requirement(struct fb_info *info,
3436
struct fb_blit_caps *caps) {}
3537
static inline void fbcon_fb_blanked(struct fb_info *info, int blank) {}
38+
static inline int fbcon_modechange_possible(struct fb_info *info,
39+
struct fb_var_screeninfo *var) { return 0; }
3640
static inline void fbcon_update_vcs(struct fb_info *info, bool all) {}
3741
static inline void fbcon_remap_all(struct fb_info *info) {}
3842
static inline int fbcon_set_con2fb_map_ioctl(void __user *argp) { return 0; }

0 commit comments

Comments
 (0)