diff options
author | Dave Airlie <airlied@redhat.com> | 2017-08-09 20:06:42 -0400 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2017-08-09 20:06:42 -0400 |
commit | db488ab0f5e6653b256d8af60033c363c2f0a9d6 (patch) | |
tree | 95d12e53fc0951ee440cb5281dc9658805bb7b2a | |
parent | 6606e9afb880acd6bcee13c9e831e88f07c8e495 (diff) | |
parent | 1899bd57570a3e610db574b57d1e7e66378aa908 (diff) |
Merge tag 'exynos-drm-fixes-for-v4.13-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos into drm-fixes
Fix a issue to display system memory region outside a gem buffer.
* tag 'exynos-drm-fixes-for-v4.13-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos:
drm/exynos: forbid creating framebuffers from too small GEM buffers
-rw-r--r-- | drivers/gpu/drm/exynos/exynos_drm_fb.c | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fb.c b/drivers/gpu/drm/exynos/exynos_drm_fb.c index d48fd7c918f8..73217c281c9a 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fb.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fb.c | |||
@@ -145,13 +145,19 @@ static struct drm_framebuffer * | |||
145 | exynos_user_fb_create(struct drm_device *dev, struct drm_file *file_priv, | 145 | exynos_user_fb_create(struct drm_device *dev, struct drm_file *file_priv, |
146 | const struct drm_mode_fb_cmd2 *mode_cmd) | 146 | const struct drm_mode_fb_cmd2 *mode_cmd) |
147 | { | 147 | { |
148 | const struct drm_format_info *info = drm_get_format_info(dev, mode_cmd); | ||
148 | struct exynos_drm_gem *exynos_gem[MAX_FB_BUFFER]; | 149 | struct exynos_drm_gem *exynos_gem[MAX_FB_BUFFER]; |
149 | struct drm_gem_object *obj; | 150 | struct drm_gem_object *obj; |
150 | struct drm_framebuffer *fb; | 151 | struct drm_framebuffer *fb; |
151 | int i; | 152 | int i; |
152 | int ret; | 153 | int ret; |
153 | 154 | ||
154 | for (i = 0; i < drm_format_num_planes(mode_cmd->pixel_format); i++) { | 155 | for (i = 0; i < info->num_planes; i++) { |
156 | unsigned int height = (i == 0) ? mode_cmd->height : | ||
157 | DIV_ROUND_UP(mode_cmd->height, info->vsub); | ||
158 | unsigned long size = height * mode_cmd->pitches[i] + | ||
159 | mode_cmd->offsets[i]; | ||
160 | |||
155 | obj = drm_gem_object_lookup(file_priv, mode_cmd->handles[i]); | 161 | obj = drm_gem_object_lookup(file_priv, mode_cmd->handles[i]); |
156 | if (!obj) { | 162 | if (!obj) { |
157 | DRM_ERROR("failed to lookup gem object\n"); | 163 | DRM_ERROR("failed to lookup gem object\n"); |
@@ -160,6 +166,12 @@ exynos_user_fb_create(struct drm_device *dev, struct drm_file *file_priv, | |||
160 | } | 166 | } |
161 | 167 | ||
162 | exynos_gem[i] = to_exynos_gem(obj); | 168 | exynos_gem[i] = to_exynos_gem(obj); |
169 | |||
170 | if (size > exynos_gem[i]->size) { | ||
171 | i++; | ||
172 | ret = -EINVAL; | ||
173 | goto err; | ||
174 | } | ||
163 | } | 175 | } |
164 | 176 | ||
165 | fb = exynos_drm_framebuffer_init(dev, mode_cmd, exynos_gem, i); | 177 | fb = exynos_drm_framebuffer_init(dev, mode_cmd, exynos_gem, i); |