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: stable@vger.kernel.org
Signed-off-by: Melbin K Mathew <redacted>
---
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