diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/video/fbcmap.c | 30 | ||||
-rw-r--r-- | drivers/video/fbmem.c | 4 |
2 files changed, 25 insertions, 9 deletions
diff --git a/drivers/video/fbcmap.c b/drivers/video/fbcmap.c index 5c3960d..31e93a5 100644 --- a/drivers/video/fbcmap.c +++ b/drivers/video/fbcmap.c @@ -166,6 +166,9 @@ int fb_copy_cmap(const struct fb_cmap *from, struct fb_cmap *to) int tooff = 0, fromoff = 0; int size; + if (!to || !from) + return -EINVAL; + if (to->start > from->start) fromoff = to->start - from->start; else @@ -177,9 +180,12 @@ int fb_copy_cmap(const struct fb_cmap *from, struct fb_cmap *to) return -EINVAL; size *= sizeof(u16); - memcpy(to->red+tooff, from->red+fromoff, size); - memcpy(to->green+tooff, from->green+fromoff, size); - memcpy(to->blue+tooff, from->blue+fromoff, size); + if (from->red && to->red) + memcpy(to->red+tooff, from->red+fromoff, size); + if (from->green && to->green) + memcpy(to->green+tooff, from->green+fromoff, size); + if (from->blue && to->blue) + memcpy(to->blue+tooff, from->blue+fromoff, size); if (from->transp && to->transp) memcpy(to->transp+tooff, from->transp+fromoff, size); return 0; @@ -190,6 +196,9 @@ int fb_cmap_to_user(const struct fb_cmap *from, struct fb_cmap_user *to) int tooff = 0, fromoff = 0; int size; + if (!to || !from) + return -EINVAL; + if (to->start > from->start) fromoff = to->start - from->start; else @@ -201,12 +210,15 @@ int fb_cmap_to_user(const struct fb_cmap *from, struct fb_cmap_user *to) return -EINVAL; size *= sizeof(u16); - if (copy_to_user(to->red+tooff, from->red+fromoff, size)) - return -EFAULT; - if (copy_to_user(to->green+tooff, from->green+fromoff, size)) - return -EFAULT; - if (copy_to_user(to->blue+tooff, from->blue+fromoff, size)) - return -EFAULT; + if (from->red && to->red) + if (copy_to_user(to->red+tooff, from->red+fromoff, size)) + return -EFAULT; + if (from->green && to->green) + if (copy_to_user(to->green+tooff, from->green+fromoff, size)) + return -EFAULT; + if (from->blue && to->blue) + if (copy_to_user(to->blue+tooff, from->blue+fromoff, size)) + return -EFAULT; if (from->transp && to->transp) if (copy_to_user(to->transp+tooff, from->transp+fromoff, size)) return -EFAULT; diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c index fcc52d4..4716e62 100644 --- a/drivers/video/fbmem.c +++ b/drivers/video/fbmem.c @@ -1108,6 +1108,10 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd, if (copy_from_user(&cmap, argp, sizeof(cmap))) return -EFAULT; ret = fb_set_user_cmap(&cmap, info); + if (ret) { + if (info) + fb_dealloc_cmap(&info->cmap); + } break; case FBIOGETCMAP: if (copy_from_user(&cmap, argp, sizeof(cmap))) |