]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blob - 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
1 From: Ben Hutchings <ben@decadent.org.uk>
2 Date: Sun, 23 Aug 2009 15:59:04 +0000 (+0100)
3 Subject: drm/r128: Add test for initialisation to all ioctls that require it
4 Patch-mainline: v2.6.32-rc1
5 Git-commit: 7dc482dfeeeefcfd000d4271c4626937406756d7
6 References: bnc#548071 CVE-2009-3620
7
8 drm/r128: Add test for initialisation to all ioctls that require it
9
10 Almost all r128's private ioctls require that the CCE state has
11 already been initialised. However, most do not test that this has
12 been done, and will proceed to dereference a null pointer. This may
13 result in a security vulnerability, since some ioctls are
14 unprivileged.
15
16 This adds a macro for the common initialisation test and changes all
17 ioctl implementations that require prior initialisation to use that
18 macro.
19
20 Also, r128_do_init_cce() does not test that the CCE state has not
21 been initialised already. Repeated initialisation may lead to a crash
22 or resource leak. This adds that test.
23
24 Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
25 Signed-off-by: Dave Airlie <airlied@redhat.com>
26 Acked-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