diff options
author | Antonino A. Daplas <adaplas@gmail.com> | 2007-08-10 16:00:47 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-08-11 18:47:40 -0400 |
commit | 9cd1c67434544b1d9a4fb4a4cdec15608167a233 (patch) | |
tree | 04c872c916fc26e78b7a492f5ecfa681e641d2fc /drivers/video/pvr2fb.c | |
parent | 4769a9a53b39f3b6a7e4d0b3c5e6b9598560818d (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.c | 12 |
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 | ||
148 | static struct fb_info *fb_info; | 149 | static 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 | ||
1132 | module_init(pvr2fb_init); | 1134 | module_init(pvr2fb_init); |