fb_set_var() can delete a mode from info->modelist when userspace passes FB_ACTIVATE_INV_MODE through FBIOPUT_VSCREENINFO. The code checks that the mode being deleted is not the current info->var and that fbcon is not using it, but it does not check fb_info->mode.
fb_info->mode may still point into the modelist entry being deleted. If the entry is freed, later mode sysfs reads through show_mode() can dereference a stale pointer. Clear fb_info->mode before calling fb_delete_videomode() when it matches the mode being removed. Cc: [email protected] Signed-off-by: Melbin K Mathew <[email protected]> --- drivers/video/fbdev/core/fbmem.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c index 2f1c56e5a7..c8aa163b0e 100644 --- a/drivers/video/fbdev/core/fbmem.c +++ b/drivers/video/fbdev/core/fbmem.c @@ -246,8 +246,11 @@ fb_set_var(struct fb_info *info, struct fb_var_screeninfo *var) ret = fb_mode_is_equal(&mode1, &mode2); if (!ret) { ret = fbcon_mode_deleted(info, &mode1); - if (!ret) + if (!ret) { + if (info->mode && fb_mode_is_equal(info->mode, &mode1)) + info->mode = NULL; fb_delete_videomode(&mode1, &info->modelist); + } } return ret ? -EINVAL : 0; -- 2.39.5
