]> git.hungrycats.org Git - linux/commitdiff
[PATCH] fbdev: fix kernel panic from FBIO_CURSOR ioctl
authorAntonino Daplas <adaplas@hotpop.com>
Tue, 31 Aug 2004 03:41:42 +0000 (20:41 -0700)
committerLinus Torvalds <torvalds@ppc970.osdl.org>
Tue, 31 Aug 2004 03:41:42 +0000 (20:41 -0700)
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
   <nothingmuch@woobling.org>.

2. This also fixes the cursor corruption in soft_cursor when
   sprite.scan_align != 1.

Signed-off-by: Antonino Daplas <adaplas@pol.net>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
drivers/video/fbmem.c
drivers/video/softcursor.c

index 5a29469372373814c1b603925009732055b73f32..3149219efa4a8f665ca238bacb0557657a16f473 100644 (file)
@@ -974,7 +974,7 @@ fb_cursor(struct fb_info *info, struct fb_cursor_user __user *sprite)
 {
        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 fb_cursor_user __user *sprite)
                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 fb_cursor_user __user *sprite)
                
                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;
 }
 
index a953b467b28252564277540beded52874ec0d6b2..7637dc870a8095e90df987aae733231c07ac855f 100644 (file)
@@ -22,7 +22,8 @@ int soft_cursor(struct fb_info *info, struct fb_cursor *cursor)
        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, struct fb_cursor *cursor)
                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, struct fb_cursor *cursor)
        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;
 }