]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/2.6.27.46/drm-r128-add-test-for-initialisation-to-all-ioctls-that-require-it.patch
4.9-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 2.6.27.46 / drm-r128-add-test-for-initialisation-to-all-ioctls-that-require-it.patch
CommitLineData
945f7f36
GKH
1From 7dc482dfeeeefcfd000d4271c4626937406756d7 Mon Sep 17 00:00:00 2001
2From: Ben Hutchings <ben@decadent.org.uk>
3Date: Sun, 23 Aug 2009 16:59:04 +0100
4Subject: drm/r128: Add test for initialisation to all ioctls that require it
5
6From: Ben Hutchings <ben@decadent.org.uk>
7
8commit 7dc482dfeeeefcfd000d4271c4626937406756d7 upstream.
9
10Almost all r128's private ioctls require that the CCE state has
11already been initialised. However, most do not test that this has
12been done, and will proceed to dereference a null pointer. This may
13result in a security vulnerability, since some ioctls are
14unprivileged.
15
16This adds a macro for the common initialisation test and changes all
17ioctl implementations that require prior initialisation to use that
18macro.
19
20Also, r128_do_init_cce() does not test that the CCE state has not
21been initialised already. Repeated initialisation may lead to a crash
22or resource leak. This adds that test.
23
24Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
25Signed-off-by: Dave Airlie <airlied@redhat.com>
26Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
27
28
29---
30 drivers/gpu/drm/r128/r128_cce.c | 18 ++++++++++++++----
31 drivers/gpu/drm/r128/r128_drv.h | 8 ++++++++
32 drivers/gpu/drm/r128/r128_state.c | 36 +++++++++++++++++++-----------------
33 3 files changed, 41 insertions(+), 21 deletions(-)
34
35--- a/drivers/gpu/drm/r128/r128_cce.c
36+++ b/drivers/gpu/drm/r128/r128_cce.c
37@@ -353,6 +353,11 @@ static int r128_do_init_cce(struct drm_d
38
39 DRM_DEBUG("\n");
40
41+ if (dev->dev_private) {
42+ DRM_DEBUG("called when already initialized\n");
43+ return -EINVAL;
44+ }
45+
46 dev_priv = drm_alloc(sizeof(drm_r128_private_t), DRM_MEM_DRIVER);
47 if (dev_priv == NULL)
48 return -ENOMEM;
49@@ -651,6 +656,8 @@ int r128_cce_start(struct drm_device *de
50
51 LOCK_TEST_WITH_RETURN(dev, file_priv);
52
53+ DEV_INIT_TEST_WITH_RETURN(dev_priv);
54+
55 if (dev_priv->cce_running || dev_priv->cce_mode == R128_PM4_NONPM4) {
56 DRM_DEBUG("while CCE running\n");
57 return 0;
58@@ -673,6 +680,8 @@ int r128_cce_stop(struct drm_device *dev
59
60 LOCK_TEST_WITH_RETURN(dev, file_priv);
61
62+ DEV_INIT_TEST_WITH_RETURN(dev_priv);
63+
64 /* Flush any pending CCE commands. This ensures any outstanding
65 * commands are exectuted by the engine before we turn it off.
66 */
67@@ -710,10 +719,7 @@ int r128_cce_reset(struct drm_device *de
68
69 LOCK_TEST_WITH_RETURN(dev, file_priv);
70
71- if (!dev_priv) {
72- DRM_DEBUG("called before init done\n");
73- return -EINVAL;
74- }
75+ DEV_INIT_TEST_WITH_RETURN(dev_priv);
76
77 r128_do_cce_reset(dev_priv);
78
79@@ -730,6 +736,8 @@ int r128_cce_idle(struct drm_device *dev
80
81 LOCK_TEST_WITH_RETURN(dev, file_priv);
82
83+ DEV_INIT_TEST_WITH_RETURN(dev_priv);
84+
85 if (dev_priv->cce_running) {
86 r128_do_cce_flush(dev_priv);
87 }
88@@ -743,6 +751,8 @@ int r128_engine_reset(struct drm_device
89
90 LOCK_TEST_WITH_RETURN(dev, file_priv);
91
92+ DEV_INIT_TEST_WITH_RETURN(dev->dev_private);
93+
94 return r128_do_engine_reset(dev);
95 }
96
97--- a/drivers/gpu/drm/r128/r128_drv.h
98+++ b/drivers/gpu/drm/r128/r128_drv.h
99@@ -418,6 +418,14 @@ static __inline__ void r128_update_ring_
100 * Misc helper macros
101 */
102
103+#define DEV_INIT_TEST_WITH_RETURN(_dev_priv) \
104+do { \
105+ if (!_dev_priv) { \
106+ DRM_ERROR("called with no initialization\n"); \
107+ return -EINVAL; \
108+ } \
109+} while (0)
110+
111 #define RING_SPACE_TEST_WITH_RETURN( dev_priv ) \
112 do { \
113 drm_r128_ring_buffer_t *ring = &dev_priv->ring; int i; \
114--- a/drivers/gpu/drm/r128/r128_state.c
115+++ b/drivers/gpu/drm/r128/r128_state.c
116@@ -1244,14 +1244,18 @@ static void r128_cce_dispatch_stipple(st
117 static int r128_cce_clear(struct drm_device *dev, void *data, struct drm_file *file_priv)
118 {
119 drm_r128_private_t *dev_priv = dev->dev_private;
120- drm_r128_sarea_t *sarea_priv = dev_priv->sarea_priv;
121+ drm_r128_sarea_t *sarea_priv;
122 drm_r128_clear_t *clear = data;
123 DRM_DEBUG("\n");
124
125 LOCK_TEST_WITH_RETURN(dev, file_priv);
126
127+ DEV_INIT_TEST_WITH_RETURN(dev_priv);
128+
129 RING_SPACE_TEST_WITH_RETURN(dev_priv);
130
131+ sarea_priv = dev_priv->sarea_priv;
132+
133 if (sarea_priv->nbox > R128_NR_SAREA_CLIPRECTS)
134 sarea_priv->nbox = R128_NR_SAREA_CLIPRECTS;
135
136@@ -1312,6 +1316,8 @@ static int r128_cce_flip(struct drm_devi
137
138 LOCK_TEST_WITH_RETURN(dev, file_priv);
139
140+ DEV_INIT_TEST_WITH_RETURN(dev_priv);
141+
142 RING_SPACE_TEST_WITH_RETURN(dev_priv);
143
144 if (!dev_priv->page_flipping)
145@@ -1331,6 +1337,8 @@ static int r128_cce_swap(struct drm_devi
146
147 LOCK_TEST_WITH_RETURN(dev, file_priv);
148
149+ DEV_INIT_TEST_WITH_RETURN(dev_priv);
150+
151 RING_SPACE_TEST_WITH_RETURN(dev_priv);
152
153 if (sarea_priv->nbox > R128_NR_SAREA_CLIPRECTS)
154@@ -1354,10 +1362,7 @@ static int r128_cce_vertex(struct drm_de
155
156 LOCK_TEST_WITH_RETURN(dev, file_priv);
157
158- if (!dev_priv) {
159- DRM_ERROR("called with no initialization\n");
160- return -EINVAL;
161- }
162+ DEV_INIT_TEST_WITH_RETURN(dev_priv);
163
164 DRM_DEBUG("pid=%d index=%d count=%d discard=%d\n",
165 DRM_CURRENTPID, vertex->idx, vertex->count, vertex->discard);
166@@ -1410,10 +1415,7 @@ static int r128_cce_indices(struct drm_d
167
168 LOCK_TEST_WITH_RETURN(dev, file_priv);
169
170- if (!dev_priv) {
171- DRM_ERROR("called with no initialization\n");
172- return -EINVAL;
173- }
174+ DEV_INIT_TEST_WITH_RETURN(dev_priv);
175
176 DRM_DEBUG("pid=%d buf=%d s=%d e=%d d=%d\n", DRM_CURRENTPID,
177 elts->idx, elts->start, elts->end, elts->discard);
178@@ -1476,6 +1478,8 @@ static int r128_cce_blit(struct drm_devi
179
180 LOCK_TEST_WITH_RETURN(dev, file_priv);
181
182+ DEV_INIT_TEST_WITH_RETURN(dev_priv);
183+
184 DRM_DEBUG("pid=%d index=%d\n", DRM_CURRENTPID, blit->idx);
185
186 if (blit->idx < 0 || blit->idx >= dma->buf_count) {
187@@ -1501,6 +1505,8 @@ static int r128_cce_depth(struct drm_dev
188
189 LOCK_TEST_WITH_RETURN(dev, file_priv);
190
191+ DEV_INIT_TEST_WITH_RETURN(dev_priv);
192+
193 RING_SPACE_TEST_WITH_RETURN(dev_priv);
194
195 ret = -EINVAL;
196@@ -1531,6 +1537,8 @@ static int r128_cce_stipple(struct drm_d
197
198 LOCK_TEST_WITH_RETURN(dev, file_priv);
199
200+ DEV_INIT_TEST_WITH_RETURN(dev_priv);
201+
202 if (DRM_COPY_FROM_USER(&mask, stipple->mask, 32 * sizeof(u32)))
203 return -EFAULT;
204
205@@ -1555,10 +1563,7 @@ static int r128_cce_indirect(struct drm_
206
207 LOCK_TEST_WITH_RETURN(dev, file_priv);
208
209- if (!dev_priv) {
210- DRM_ERROR("called with no initialization\n");
211- return -EINVAL;
212- }
213+ DEV_INIT_TEST_WITH_RETURN(dev_priv);
214
215 DRM_DEBUG("idx=%d s=%d e=%d d=%d\n",
216 indirect->idx, indirect->start, indirect->end,
217@@ -1620,10 +1625,7 @@ static int r128_getparam(struct drm_devi
218 drm_r128_getparam_t *param = data;
219 int value;
220
221- if (!dev_priv) {
222- DRM_ERROR("called with no initialization\n");
223- return -EINVAL;
224- }
225+ DEV_INIT_TEST_WITH_RETURN(dev_priv);
226
227 DRM_DEBUG("pid=%d\n", DRM_CURRENTPID);
228