提交 cf76e174 编写于 作者: H Helge Deller 提交者: Yongqiang Liu

fbcon: Prevent that screen size is smaller than font size

mainline inclusion
from mainline-v5.19-rc6
commit e64242ca
category: bugfix
bugzilla: https://gitee.com/src-openeuler/kernel/issues/I5IQ4M
CVE: CVE-2021-33655

--------------------------------

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: NHelge Deller <deller@gmx.de>
Reviewed-by: NGeert Uytterhoeven <geert@linux-m68k.org>
Cc: stable@vger.kernel.org # v5.4+
Signed-off-by: NChen Jun <chenjun102@huawei.com>

Conflicts:
	drivers/video/fbdev/core/fbcon.c
	drivers/video/fbdev/core/fbmem.c
	include/linux/fbcon.h
Reviewed-by: NXiu Jianfeng <xiujianfeng@huawei.com>
Reviewed-by: NWeilong Chen <chenweilong@huawei.com>
Signed-off-by: NYongqiang Liu <liuyongqiang13@huawei.com>
上级 4040e24b
......@@ -2702,6 +2702,34 @@ static void fbcon_set_all_vcs(struct fb_info *info)
fbcon_modechanged(info);
}
/* let fbcon check if it supports a new screen resolution */
int fbcon_modechange_possible(struct fb_info *info, struct fb_var_screeninfo *var)
{
struct fbcon_ops *ops = info->fbcon_par;
struct vc_data *vc;
unsigned int i;
WARN_CONSOLE_UNLOCKED();
if (!ops)
return 0;
/* prevent setting a screen size which is smaller than font size */
for (i = first_fb_vc; i <= last_fb_vc; i++) {
vc = vc_cons[i].d;
if (!vc || vc->vc_mode != KD_TEXT ||
registered_fb[con2fb_map[i]] != info)
continue;
if (vc->vc_font.width > FBCON_SWAP(var->rotate, var->xres, var->yres) ||
vc->vc_font.height > FBCON_SWAP(var->rotate, var->yres, var->xres))
return -EINVAL;
}
return 0;
}
EXPORT_SYMBOL_GPL(fbcon_modechange_possible);
static int fbcon_mode_deleted(struct fb_info *info,
struct fb_videomode *mode)
{
......
......@@ -1121,9 +1121,12 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd,
console_unlock();
return -ENODEV;
}
info->flags |= FBINFO_MISC_USEREVENT;
ret = fb_set_var(info, &var);
info->flags &= ~FBINFO_MISC_USEREVENT;
ret = fbcon_modechange_possible(info, &var);
if (!ret) {
info->flags |= FBINFO_MISC_USEREVENT;
ret = fb_set_var(info, &var);
info->flags &= ~FBINFO_MISC_USEREVENT;
}
unlock_fb_info(info);
console_unlock();
if (!ret && copy_to_user(argp, &var, sizeof(var)))
......
......@@ -4,9 +4,13 @@
#ifdef CONFIG_FRAMEBUFFER_CONSOLE
void __init fb_console_init(void);
void __exit fb_console_exit(void);
int fbcon_modechange_possible(struct fb_info *info,
struct fb_var_screeninfo *var);
#else
static inline void fb_console_init(void) {}
static inline void fb_console_exit(void) {}
static inline int fbcon_modechange_possible(struct fb_info *info,
struct fb_var_screeninfo *var) { return 0; }
#endif
#endif /* _LINUX_FBCON_H */
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册