diff options
author | Zheyu Ma <zheyuma97@gmail.com> | 2022-08-03 12:23:12 +0300 |
---|---|---|
committer | Helge Deller <deller@gmx.de> | 2022-08-03 16:13:15 +0300 |
commit | 2f1c4523f7a3aaabe7e53d3ebd378292947e95c8 (patch) | |
tree | ad21f8e75f6d09410e326f4bf9c78f194449e91d /drivers/video/fbdev/arkfb.c | |
parent | c5c7502e960d9128eae1a5663fb62506d8685ac3 (diff) | |
download | linux-2f1c4523f7a3aaabe7e53d3ebd378292947e95c8.tar.xz |
video: fbdev: arkfb: Fix a divide-by-zero bug in ark_set_pixclock()
Since the user can control the arguments of the ioctl() from the user
space, under special arguments that may result in a divide-by-zero bug
in:
drivers/video/fbdev/arkfb.c:784: ark_set_pixclock(info, (hdiv * info->var.pixclock) / hmul);
with hdiv=1, pixclock=1 and hmul=2 you end up with (1*1)/2 = (int) 0.
and then in:
drivers/video/fbdev/arkfb.c:504: rv = dac_set_freq(par->dac, 0, 1000000000 / pixclock);
we'll get a division-by-zero.
The following log can reveal it:
divide error: 0000 [#1] PREEMPT SMP KASAN PTI
RIP: 0010:ark_set_pixclock drivers/video/fbdev/arkfb.c:504 [inline]
RIP: 0010:arkfb_set_par+0x10fc/0x24c0 drivers/video/fbdev/arkfb.c:784
Call Trace:
fb_set_var+0x604/0xeb0 drivers/video/fbdev/core/fbmem.c:1034
do_fb_ioctl+0x234/0x670 drivers/video/fbdev/core/fbmem.c:1110
fb_ioctl+0xdd/0x130 drivers/video/fbdev/core/fbmem.c:1189
Fix this by checking the argument of ark_set_pixclock() first.
Fixes: 681e14730c73 ("arkfb: new framebuffer driver for ARK Logic cards")
Signed-off-by: Zheyu Ma <zheyuma97@gmail.com>
Signed-off-by: Helge Deller <deller@gmx.de>
Diffstat (limited to 'drivers/video/fbdev/arkfb.c')
-rw-r--r-- | drivers/video/fbdev/arkfb.c | 7 |
1 files changed, 6 insertions, 1 deletions
diff --git a/drivers/video/fbdev/arkfb.c b/drivers/video/fbdev/arkfb.c index eb3e47c58c5f..ed76ddc7df3d 100644 --- a/drivers/video/fbdev/arkfb.c +++ b/drivers/video/fbdev/arkfb.c @@ -781,7 +781,12 @@ static int arkfb_set_par(struct fb_info *info) return -EINVAL; } - ark_set_pixclock(info, (hdiv * info->var.pixclock) / hmul); + value = (hdiv * info->var.pixclock) / hmul; + if (!value) { + fb_dbg(info, "invalid pixclock\n"); + value = 1; + } + ark_set_pixclock(info, value); svga_set_timings(par->state.vgabase, &ark_timing_regs, &(info->var), hmul, hdiv, (info->var.vmode & FB_VMODE_DOUBLE) ? 2 : 1, (info->var.vmode & FB_VMODE_INTERLACED) ? 2 : 1, |