[PATCH 4/4] drm/exynos: check if framebuffer and gem size are valid or not.
Inki Dae
inki.dae at samsung.com
Fri Jun 29 01:02:56 PDT 2012
with addfb request by user, wrong framebuffer or gem size could be sent
to kernel side so this could induce invalid memory access by dma of a device.
this patch checks if framebuffer and gem size are valid or not to avoid
this issue.
Signed-off-by: Inki Dae <inki.dae at samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park at samsung.com>
---
drivers/gpu/drm/exynos/exynos_drm_fb.c | 48 ++++++++++++++++++++++++++++++-
1 files changed, 46 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fb.c b/drivers/gpu/drm/exynos/exynos_drm_fb.c
index 6aba1e5..ce0f18d 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fb.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fb.c
@@ -65,6 +65,45 @@ static int check_fb_gem_memory_type(struct drm_device *drm_dev,
return 0;
}
+static int check_fb_gem_size(struct drm_device *drm_dev,
+ struct drm_framebuffer *fb,
+ unsigned int nr)
+{
+ unsigned long fb_size;
+ struct drm_gem_object *obj;
+ struct exynos_drm_gem_obj *exynos_gem_obj;
+ struct exynos_drm_fb *exynos_fb = to_exynos_fb(fb);
+
+ /* in case of RGB format, only one plane is used. */
+ if (nr < 2) {
+ exynos_gem_obj = exynos_fb->exynos_gem_obj[0];
+ obj = &exynos_gem_obj->base;
+ fb_size = fb->width * ((fb->bits_per_pixel + 7) >> 3)
+ * fb->height;
+
+ if (fb_size != exynos_gem_obj->packed_size) {
+ DRM_ERROR("invalid fb or gem size.\n");
+ return -EINVAL;
+ }
+ /* in case of NV12MT, YUV420M and so on, two and three planes. */
+ } else {
+ unsigned int i;
+
+ for (i = 0; i < nr; i++) {
+ exynos_gem_obj = exynos_fb->exynos_gem_obj[i];
+ obj = &exynos_gem_obj->base;
+ fb_size = fb->pitches[i] * fb->height;
+
+ if (fb_size != exynos_gem_obj->packed_size) {
+ DRM_ERROR("invalid fb or gem size.\n");
+ return -EINVAL;
+ }
+ }
+ }
+
+ return 0;
+}
+
static void exynos_drm_fb_destroy(struct drm_framebuffer *fb)
{
struct exynos_drm_fb *exynos_fb = to_exynos_fb(fb);
@@ -160,8 +199,7 @@ exynos_user_fb_create(struct drm_device *dev, struct drm_file *file_priv,
struct drm_gem_object *obj;
struct drm_framebuffer *fb;
struct exynos_drm_fb *exynos_fb;
- int nr;
- int i;
+ int nr, i, ret;
DRM_DEBUG_KMS("%s\n", __FILE__);
@@ -204,6 +242,12 @@ exynos_user_fb_create(struct drm_device *dev, struct drm_file *file_priv,
exynos_fb->exynos_gem_obj[i] = to_exynos_gem_obj(obj);
}
+ ret = check_fb_gem_size(dev, fb, nr);
+ if (ret < 0) {
+ exynos_drm_fb_destroy(fb);
+ return ERR_PTR(ret);
+ }
+
return fb;
}
--
1.7.4.1
More information about the dri-devel
mailing list