From: "Antonino A. Daplas" 1. This fixes a kernel oops when issuing an FBIO_CURSOR ioctl if struct fb_cursor_user is filled with zero/NULLs. Reported by Yuval Kogman . 2. This also fixes the cursor corruption in soft_cursor when sprite.scan_align != 1. Signed-off-by: Antonino Daplas Signed-off-by: Andrew Morton --- 25-akpm/drivers/video/fbmem.c | 18 +++++++++++------- 25-akpm/drivers/video/softcursor.c | 18 +++++++++++++++--- 2 files changed, 26 insertions(+), 10 deletions(-) diff -puN drivers/video/fbmem.c~fbdev-fix-kernel-panic-from-fbio_cursor-ioctl drivers/video/fbmem.c --- 25/drivers/video/fbmem.c~fbdev-fix-kernel-panic-from-fbio_cursor-ioctl 2004-08-30 22:20:55.384756120 -0700 +++ 25-akpm/drivers/video/fbmem.c 2004-08-30 22:20:55.389755360 -0700 @@ -974,7 +974,7 @@ fb_cursor(struct fb_info *info, struct f { struct fb_cursor_user cursor_user; struct fb_cursor cursor; - char *data = NULL, *mask = NULL; + char *data = NULL, *mask = NULL, *info_mask = NULL; u16 *red = NULL, *green = NULL, *blue = NULL, *transp = NULL; int err = -EINVAL; @@ -982,12 +982,12 @@ fb_cursor(struct fb_info *info, struct f return -EFAULT; memcpy(&cursor, &cursor_user, sizeof(cursor_user)); - cursor.mask = NULL; - cursor.image.data = NULL; - cursor.image.cmap.red = NULL; - cursor.image.cmap.green = NULL; - cursor.image.cmap.blue = NULL; - cursor.image.cmap.transp = NULL; + cursor.mask = info->cursor.mask; + cursor.image.data = info->cursor.image.data; + cursor.image.cmap.red = info->cursor.image.cmap.red; + cursor.image.cmap.green = info->cursor.image.cmap.green; + cursor.image.cmap.blue = info->cursor.image.cmap.blue; + cursor.image.cmap.transp = info->cursor.image.cmap.transp; cursor.data = NULL; if (cursor.set & FB_CUR_SETCUR) @@ -1047,6 +1047,8 @@ fb_cursor(struct fb_info *info, struct f cursor.image.data = data; cursor.mask = mask; + info_mask = (char *) info->cursor.mask; + info->cursor.mask = mask; } info->cursor.set = cursor.set; info->cursor.rop = cursor.rop; @@ -1058,6 +1060,8 @@ out: kfree(green); kfree(blue); kfree(transp); + if (info_mask) + info->cursor.mask = info_mask; return err; } diff -puN drivers/video/softcursor.c~fbdev-fix-kernel-panic-from-fbio_cursor-ioctl drivers/video/softcursor.c --- 25/drivers/video/softcursor.c~fbdev-fix-kernel-panic-from-fbio_cursor-ioctl 2004-08-30 22:20:55.385755968 -0700 +++ 25-akpm/drivers/video/softcursor.c 2004-08-30 22:20:55.390755208 -0700 @@ -22,7 +22,8 @@ int soft_cursor(struct fb_info *info, st unsigned int scan_align = info->sprite.scan_align - 1; unsigned int buf_align = info->sprite.buf_align - 1; unsigned int i, size, dsize, s_pitch, d_pitch; - u8 *dst, src[64]; + struct fb_cursor *cur; + u8 *dst, *src; if (cursor->set & FB_CUR_SETSIZE) { info->cursor.image.height = cursor->image.height; @@ -48,9 +49,17 @@ int soft_cursor(struct fb_info *info, st info->cursor.image.depth = cursor->image.depth; } + info->cursor.image.data = cursor->image.data; + if (info->state != FBINFO_STATE_RUNNING) return 0; + src = kmalloc(64 + sizeof(struct fb_cursor), GFP_ATOMIC); + if (!src) + return -ENOMEM; + cur = (struct fb_cursor *) (src + 64); + *cur = info->cursor; + s_pitch = (info->cursor.image.width + 7) >> 3; dsize = s_pitch * info->cursor.image.height; d_pitch = (s_pitch + scan_align) & ~scan_align; @@ -79,9 +88,12 @@ int soft_cursor(struct fb_info *info, st else fb_sysmove_buf_aligned(info, &info->sprite, dst, d_pitch, src, s_pitch, info->cursor.image.height); - info->cursor.image.data = dst; + cur->image.data = dst; - info->fbops->fb_imageblit(info, &info->cursor.image); + info->fbops->fb_imageblit(info, &cur->image); + + kfree(src); + return 0; } _