summaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
authorZheyu Ma <zheyuma97@gmail.com>2022-03-02 22:33:11 +0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2022-04-20 09:06:40 +0200
commitfb791514acf9070225eed46e1ccbb0aa7aae5da5 (patch)
treed758078881ead0ff3fecccb50b8d6afe4fc817e8 /drivers/video
parent734ff1117d5f7d7ca41bda5666366bb95fbc062b (diff)
downloadlinux-stable-fb791514acf9070225eed46e1ccbb0aa7aae5da5.tar.gz
linux-stable-fb791514acf9070225eed46e1ccbb0aa7aae5da5.tar.bz2
linux-stable-fb791514acf9070225eed46e1ccbb0aa7aae5da5.zip
video: fbdev: sm712fb: Fix crash in smtcfb_write()
[ Upstream commit 4f01d09b2bbfbcb47b3eb305560a7f4857a32260 ] When the sm712fb driver writes three bytes to the framebuffer, the driver will crash: BUG: unable to handle page fault for address: ffffc90001ffffff RIP: 0010:smtcfb_write+0x454/0x5b0 Call Trace: vfs_write+0x291/0xd60 ? do_sys_openat2+0x27d/0x350 ? __fget_light+0x54/0x340 ksys_write+0xce/0x190 do_syscall_64+0x43/0x90 entry_SYSCALL_64_after_hwframe+0x44/0xae Fix it by removing the open-coded endianness fixup-code. Signed-off-by: Zheyu Ma <zheyuma97@gmail.com> Signed-off-by: Helge Deller <deller@gmx.de> Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/fbdev/sm712fb.c21
1 files changed, 4 insertions, 17 deletions
diff --git a/drivers/video/fbdev/sm712fb.c b/drivers/video/fbdev/sm712fb.c
index 841fd0c7ce9b..620f3152213a 100644
--- a/drivers/video/fbdev/sm712fb.c
+++ b/drivers/video/fbdev/sm712fb.c
@@ -1118,7 +1118,7 @@ static ssize_t smtcfb_write(struct fb_info *info, const char __user *buf,
count = total_size - p;
}
- buffer = kmalloc((count > PAGE_SIZE) ? PAGE_SIZE : count, GFP_KERNEL);
+ buffer = kmalloc(PAGE_SIZE, GFP_KERNEL);
if (!buffer)
return -ENOMEM;
@@ -1136,24 +1136,11 @@ static ssize_t smtcfb_write(struct fb_info *info, const char __user *buf,
break;
}
- for (i = c >> 2; i--;) {
- fb_writel(big_swap(*src), dst++);
+ for (i = (c + 3) >> 2; i--;) {
+ fb_writel(big_swap(*src), dst);
+ dst++;
src++;
}
- if (c & 3) {
- u8 *src8 = (u8 *)src;
- u8 __iomem *dst8 = (u8 __iomem *)dst;
-
- for (i = c & 3; i--;) {
- if (i & 1) {
- fb_writeb(*src8++, ++dst8);
- } else {
- fb_writeb(*src8++, --dst8);
- dst8 += 2;
- }
- }
- dst = (u32 __iomem *)dst8;
- }
*ppos += c;
buf += c;