aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/pvr2fb.c
diff options
context:
space:
mode:
authorAntonino A. Daplas <adaplas@gmail.com>2007-08-10 16:00:47 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-08-11 18:47:40 -0400
commit9cd1c67434544b1d9a4fb4a4cdec15608167a233 (patch)
tree04c872c916fc26e78b7a492f5ecfa681e641d2fc /drivers/video/pvr2fb.c
parent4769a9a53b39f3b6a7e4d0b3c5e6b9598560818d (diff)
pvr2fb: Fix oops when pseudo_palette is written
Reported by: Adrian McMenamin <adrianmcmenamin@gmail.com> This driver will oops when the pseudo_palette[] is written as u32 but not when written as u16. When written as u32, it corrupts the adjacent 'mmio_base' field of struct pvr2fb_par. Fix by using framebuffer_alloc()/release() to allocate struct fb_info and struct pvr2fb_par, and create the pseudo_palette[] as part of struct pvr2fb_par. Signed-off-by: Antonino Daplas <adaplas@gmail.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/video/pvr2fb.c')
-rw-r--r--drivers/video/pvr2fb.c12
1 files changed, 7 insertions, 5 deletions
diff --git a/drivers/video/pvr2fb.c b/drivers/video/pvr2fb.c
index f9300266044d..a72921b552dc 100644
--- a/drivers/video/pvr2fb.c
+++ b/drivers/video/pvr2fb.c
@@ -143,6 +143,7 @@ static struct pvr2fb_par {
143 unsigned char is_lowres; /* Is horizontal pixel-doubling enabled? */ 143 unsigned char is_lowres; /* Is horizontal pixel-doubling enabled? */
144 144
145 unsigned long mmio_base; /* MMIO base */ 145 unsigned long mmio_base; /* MMIO base */
146 u32 palette[16];
146} *currentpar; 147} *currentpar;
147 148
148static struct fb_info *fb_info; 149static struct fb_info *fb_info;
@@ -790,7 +791,7 @@ static int __devinit pvr2fb_common_init(void)
790 fb_info->fbops = &pvr2fb_ops; 791 fb_info->fbops = &pvr2fb_ops;
791 fb_info->fix = pvr2_fix; 792 fb_info->fix = pvr2_fix;
792 fb_info->par = currentpar; 793 fb_info->par = currentpar;
793 fb_info->pseudo_palette = (void *)(fb_info->par + 1); 794 fb_info->pseudo_palette = currentpar->palette;
794 fb_info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN; 795 fb_info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN;
795 796
796 if (video_output == VO_VGA) 797 if (video_output == VO_VGA)
@@ -1082,14 +1083,15 @@ static int __init pvr2fb_init(void)
1082#endif 1083#endif
1083 size = sizeof(struct fb_info) + sizeof(struct pvr2fb_par) + 16 * sizeof(u32); 1084 size = sizeof(struct fb_info) + sizeof(struct pvr2fb_par) + 16 * sizeof(u32);
1084 1085
1085 fb_info = kzalloc(size, GFP_KERNEL); 1086 fb_info = framebuffer_alloc(sizeof(struct pvr2fb_par), NULL);
1087
1086 if (!fb_info) { 1088 if (!fb_info) {
1087 printk(KERN_ERR "Failed to allocate memory for fb_info\n"); 1089 printk(KERN_ERR "Failed to allocate memory for fb_info\n");
1088 return -ENOMEM; 1090 return -ENOMEM;
1089 } 1091 }
1090 1092
1091 1093
1092 currentpar = (struct pvr2fb_par *)(fb_info + 1); 1094 currentpar = fb_info->par;
1093 1095
1094 for (i = 0; i < ARRAY_SIZE(board_driver); i++) { 1096 for (i = 0; i < ARRAY_SIZE(board_driver); i++) {
1095 struct pvr2_board *pvr_board = board_driver + i; 1097 struct pvr2_board *pvr_board = board_driver + i;
@@ -1102,7 +1104,7 @@ static int __init pvr2fb_init(void)
1102 if (ret != 0) { 1104 if (ret != 0) {
1103 printk(KERN_ERR "pvr2fb: Failed init of %s device\n", 1105 printk(KERN_ERR "pvr2fb: Failed init of %s device\n",
1104 pvr_board->name); 1106 pvr_board->name);
1105 kfree(fb_info); 1107 framebuffer_release(fb_info);
1106 break; 1108 break;
1107 } 1109 }
1108 } 1110 }
@@ -1126,7 +1128,7 @@ static void __exit pvr2fb_exit(void)
1126#endif 1128#endif
1127 1129
1128 unregister_framebuffer(fb_info); 1130 unregister_framebuffer(fb_info);
1129 kfree(fb_info); 1131 framebuffer_release(fb_info);
1130} 1132}
1131 1133
1132module_init(pvr2fb_init); 1134module_init(pvr2fb_init);