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