Gentoo Websites Logo
Go to: Gentoo Home Documentation Forums Lists Bugs Planet Store Wiki Get Gentoo!
View | Details | Raw Unified | Return to bug 81294
Collapse All | Expand All

(-)x/drivers/char/drm/drm_os_linux.h (-3 lines)
Lines 66-74 Link Here
66
	__copy_to_user(arg1, arg2, arg3)
66
	__copy_to_user(arg1, arg2, arg3)
67
#define DRM_GET_USER_UNCHECKED(val, uaddr)		\
67
#define DRM_GET_USER_UNCHECKED(val, uaddr)		\
68
	__get_user(val, uaddr)
68
	__get_user(val, uaddr)
69
#define DRM_PUT_USER_UNCHECKED(uaddr, val)		\
70
	__put_user(val, uaddr)
71
72
69
73
/** 'malloc' without the overhead of DRM(alloc)() */
70
/** 'malloc' without the overhead of DRM(alloc)() */
74
#define DRM_MALLOC(x) kmalloc(x, GFP_KERNEL)
71
#define DRM_MALLOC(x) kmalloc(x, GFP_KERNEL)
(-)x/drivers/char/drm/radeon_drv.h (-13 / +15 lines)
Lines 885-909 Link Here
885
} while (0)
885
} while (0)
886
886
887
887
888
#define OUT_RING_USER_TABLE( tab, sz ) do {			\
888
#define OUT_RING_TABLE( tab, sz ) do {					\
889
	int _size = (sz);					\
889
	int _size = (sz);					\
890
	int __user *_tab = (tab);					\
890
	int *_tab = (int *)(tab);				\
891
								\
891
								\
892
	if (write + _size > mask) {				\
892
	if (write + _size > mask) {				\
893
		int i = (mask+1) - write;			\
893
		int _i = (mask+1) - write;			\
894
		if (DRM_COPY_FROM_USER_UNCHECKED( (int *)(ring+write),	\
894
		_size -= _i;					\
895
				      _tab, i*4 ))		\
895
		while (_i > 0 ) {				\
896
			return DRM_ERR(EFAULT);		\
896
			*(int *)(ring + write) = *_tab++;	\
897
			write++;				\
898
			_i--;					\
899
		}						\
897
		write = 0;					\
900
		write = 0;					\
898
		_size -= i;					\
901
		_tab += _i;					\
899
		_tab += i;					\
900
	}							\
902
	}							\
901
								\
903
								\
902
	if (_size && DRM_COPY_FROM_USER_UNCHECKED( (int *)(ring+write),	\
904
	while (_size > 0) {					\
903
			               _tab, _size*4 ))		\
905
		*(ring + write) = *_tab++;			\
904
		return DRM_ERR(EFAULT);			\
906
		write++;					\
905
								\
907
		_size--;					\
906
	write += _size;						\
908
	}							\
907
	write &= mask;						\
909
	write &= mask;						\
908
} while (0)
910
} while (0)
909
911
(-)x/drivers/char/drm/radeon_state.c (-87 / +68 lines)
Lines 61-81 Link Here
61
	return 0;
61
	return 0;
62
}
62
}
63
63
64
static __inline__ int radeon_check_and_fixup_offset_user( drm_radeon_private_t *dev_priv,
65
							  drm_file_t *filp_priv,
66
							  u32 __user *offset ) {
67
	u32 off;
68
69
	DRM_GET_USER_UNCHECKED( off, offset );
70
71
	if ( radeon_check_and_fixup_offset( dev_priv, filp_priv, &off ) )
72
		return DRM_ERR( EINVAL );
73
74
	DRM_PUT_USER_UNCHECKED( offset, off );
75
76
	return 0;
77
}
78
79
static __inline__ int radeon_check_and_fixup_packets( drm_radeon_private_t *dev_priv,
64
static __inline__ int radeon_check_and_fixup_packets( drm_radeon_private_t *dev_priv,
80
						      drm_file_t *filp_priv,
65
						      drm_file_t *filp_priv,
81
						      int id,
66
						      int id,
Lines 83-100 Link Here
83
	switch ( id ) {
68
	switch ( id ) {
84
69
85
	case RADEON_EMIT_PP_MISC:
70
	case RADEON_EMIT_PP_MISC:
86
		if ( radeon_check_and_fixup_offset_user( dev_priv, filp_priv,
71
		if ( radeon_check_and_fixup_offset( dev_priv, filp_priv,
87
							 &data[( RADEON_RB3D_DEPTHOFFSET
72
						    &data[( RADEON_RB3D_DEPTHOFFSET
88
								 - RADEON_PP_MISC ) / 4] ) ) {
73
							    - RADEON_PP_MISC ) / 4] ) ) {
89
			DRM_ERROR( "Invalid depth buffer offset\n" );
74
			DRM_ERROR( "Invalid depth buffer offset\n" );
90
			return DRM_ERR( EINVAL );
75
			return DRM_ERR( EINVAL );
91
		}
76
		}
92
		break;
77
		break;
93
78
94
	case RADEON_EMIT_PP_CNTL:
79
	case RADEON_EMIT_PP_CNTL:
95
		if ( radeon_check_and_fixup_offset_user( dev_priv, filp_priv,
80
		if ( radeon_check_and_fixup_offset( dev_priv, filp_priv,
96
							 &data[( RADEON_RB3D_COLOROFFSET
81
						    &data[( RADEON_RB3D_COLOROFFSET
97
								 - RADEON_PP_CNTL ) / 4] ) ) {
82
							    - RADEON_PP_CNTL ) / 4] ) ) {
98
			DRM_ERROR( "Invalid colour buffer offset\n" );
83
			DRM_ERROR( "Invalid colour buffer offset\n" );
99
			return DRM_ERR( EINVAL );
84
			return DRM_ERR( EINVAL );
100
		}
85
		}
Lines 106-113 Link Here
106
	case R200_EMIT_PP_TXOFFSET_3:
91
	case R200_EMIT_PP_TXOFFSET_3:
107
	case R200_EMIT_PP_TXOFFSET_4:
92
	case R200_EMIT_PP_TXOFFSET_4:
108
	case R200_EMIT_PP_TXOFFSET_5:
93
	case R200_EMIT_PP_TXOFFSET_5:
109
		if ( radeon_check_and_fixup_offset_user( dev_priv, filp_priv,
94
		if ( radeon_check_and_fixup_offset( dev_priv, filp_priv,
110
							 &data[0] ) ) {
95
						    &data[0] ) ) {
111
			DRM_ERROR( "Invalid R200 texture offset\n" );
96
			DRM_ERROR( "Invalid R200 texture offset\n" );
112
			return DRM_ERR( EINVAL );
97
			return DRM_ERR( EINVAL );
113
		}
98
		}
Lines 116-124 Link Here
116
	case RADEON_EMIT_PP_TXFILTER_0:
101
	case RADEON_EMIT_PP_TXFILTER_0:
117
	case RADEON_EMIT_PP_TXFILTER_1:
102
	case RADEON_EMIT_PP_TXFILTER_1:
118
	case RADEON_EMIT_PP_TXFILTER_2:
103
	case RADEON_EMIT_PP_TXFILTER_2:
119
		if ( radeon_check_and_fixup_offset_user( dev_priv, filp_priv,
104
		if ( radeon_check_and_fixup_offset( dev_priv, filp_priv,
120
							 &data[( RADEON_PP_TXOFFSET_0
105
						    &data[( RADEON_PP_TXOFFSET_0
121
								 - RADEON_PP_TXFILTER_0 ) / 4] ) ) {
106
							    - RADEON_PP_TXFILTER_0 ) / 4] ) ) {
122
			DRM_ERROR( "Invalid R100 texture offset\n" );
107
			DRM_ERROR( "Invalid R100 texture offset\n" );
123
			return DRM_ERR( EINVAL );
108
			return DRM_ERR( EINVAL );
124
		}
109
		}
Lines 132-140 Link Here
132
	case R200_EMIT_PP_CUBIC_OFFSETS_5: {
117
	case R200_EMIT_PP_CUBIC_OFFSETS_5: {
133
		int i;
118
		int i;
134
		for ( i = 0; i < 5; i++ ) {
119
		for ( i = 0; i < 5; i++ ) {
135
			if ( radeon_check_and_fixup_offset_user( dev_priv,
120
			if ( radeon_check_and_fixup_offset( dev_priv, filp_priv,
136
								 filp_priv,
121
							    &data[i] ) ) {
137
								 &data[i] ) ) {
138
				DRM_ERROR( "Invalid R200 cubic texture offset\n" );
122
				DRM_ERROR( "Invalid R200 cubic texture offset\n" );
139
				return DRM_ERR( EINVAL );
123
				return DRM_ERR( EINVAL );
140
			}
124
			}
Lines 217-233 Link Here
217
						      drm_file_t *filp_priv,
201
						      drm_file_t *filp_priv,
218
						      drm_radeon_cmd_buffer_t *cmdbuf,
202
						      drm_radeon_cmd_buffer_t *cmdbuf,
219
						      unsigned int *cmdsz ) {
203
						      unsigned int *cmdsz ) {
220
	u32 tmp[4];
204
	u32 *cmd = (u32 *) cmdbuf->buf;
221
	u32 __user *cmd = (u32 __user *)cmdbuf->buf;
222
223
	if ( DRM_COPY_FROM_USER_UNCHECKED( tmp, cmd, sizeof( tmp ) ) ) {
224
		DRM_ERROR( "Failed to copy data from user space\n" );
225
		return DRM_ERR( EFAULT );
226
	}
227
205
228
	*cmdsz = 2 + ( ( tmp[0] & RADEON_CP_PACKET_COUNT_MASK ) >> 16 );
206
	*cmdsz = 2 + ( ( cmd[0] & RADEON_CP_PACKET_COUNT_MASK ) >> 16 );
229
207
230
	if ( ( tmp[0] & 0xc0000000 ) != RADEON_CP_PACKET3 ) {
208
	if ( ( cmd[0] & 0xc0000000 ) != RADEON_CP_PACKET3 ) {
231
		DRM_ERROR( "Not a type 3 packet\n" );
209
		DRM_ERROR( "Not a type 3 packet\n" );
232
		return DRM_ERR( EINVAL );
210
		return DRM_ERR( EINVAL );
233
	}
211
	}
Lines 238-269 Link Here
238
	}
216
	}
239
217
240
	/* Check client state and fix it up if necessary */
218
	/* Check client state and fix it up if necessary */
241
	if ( tmp[0] & 0x8000 ) { /* MSB of opcode: next DWORD GUI_CNTL */
219
	if ( cmd[0] & 0x8000 ) { /* MSB of opcode: next DWORD GUI_CNTL */
242
		u32 offset;
220
		u32 offset;
243
221
244
		if ( tmp[1] & ( RADEON_GMC_SRC_PITCH_OFFSET_CNTL
222
		if ( cmd[1] & ( RADEON_GMC_SRC_PITCH_OFFSET_CNTL
245
			      | RADEON_GMC_DST_PITCH_OFFSET_CNTL ) ) {
223
			      | RADEON_GMC_DST_PITCH_OFFSET_CNTL ) ) {
246
			offset = tmp[2] << 10;
224
			offset = cmd[2] << 10;
247
			if ( radeon_check_and_fixup_offset( dev_priv, filp_priv, &offset ) ) {
225
			if ( radeon_check_and_fixup_offset( dev_priv, filp_priv, &offset ) ) {
248
				DRM_ERROR( "Invalid first packet offset\n" );
226
				DRM_ERROR( "Invalid first packet offset\n" );
249
				return DRM_ERR( EINVAL );
227
				return DRM_ERR( EINVAL );
250
			}
228
			}
251
			tmp[2] = ( tmp[2] & 0xffc00000 ) | offset >> 10;
229
			cmd[2] = ( cmd[2] & 0xffc00000 ) | offset >> 10;
252
		}
230
		}
253
231
254
		if ( ( tmp[1] & RADEON_GMC_SRC_PITCH_OFFSET_CNTL ) &&
232
		if ( ( cmd[1] & RADEON_GMC_SRC_PITCH_OFFSET_CNTL ) &&
255
		     ( tmp[1] & RADEON_GMC_DST_PITCH_OFFSET_CNTL ) ) {
233
		     ( cmd[1] & RADEON_GMC_DST_PITCH_OFFSET_CNTL ) ) {
256
			offset = tmp[3] << 10;
234
			offset = cmd[3] << 10;
257
			if ( radeon_check_and_fixup_offset( dev_priv, filp_priv, &offset ) ) {
235
			if ( radeon_check_and_fixup_offset( dev_priv, filp_priv, &offset ) ) {
258
				DRM_ERROR( "Invalid second packet offset\n" );
236
				DRM_ERROR( "Invalid second packet offset\n" );
259
				return DRM_ERR( EINVAL );
237
				return DRM_ERR( EINVAL );
260
			}
238
			}
261
			tmp[3] = ( tmp[3] & 0xffc00000 ) | offset >> 10;
239
			cmd[3] = ( cmd[3] & 0xffc00000 ) | offset >> 10;
262
		}
263
264
		if ( DRM_COPY_TO_USER_UNCHECKED( cmd, tmp, sizeof( tmp ) ) ) {
265
			DRM_ERROR( "Failed to copy data to user space\n" );
266
			return DRM_ERR( EFAULT );
267
		}
240
		}
268
	}
241
	}
269
242
Lines 2087-2093 Link Here
2087
{
2060
{
2088
	int id = (int)header.packet.packet_id;
2061
	int id = (int)header.packet.packet_id;
2089
	int sz, reg;
2062
	int sz, reg;
2090
	int __user *data = (int __user *)cmdbuf->buf;
2063
	int *data = (int *)cmdbuf->buf;
2091
	RING_LOCALS;
2064
	RING_LOCALS;
2092
   
2065
   
2093
	if (id >= RADEON_MAX_STATE_PACKETS)
2066
	if (id >= RADEON_MAX_STATE_PACKETS)
Lines 2108-2114 Link Here
2108
2081
2109
	BEGIN_RING(sz+1);
2082
	BEGIN_RING(sz+1);
2110
	OUT_RING( CP_PACKET0( reg, (sz-1) ) );
2083
	OUT_RING( CP_PACKET0( reg, (sz-1) ) );
2111
	OUT_RING_USER_TABLE( data, sz );
2084
	OUT_RING_TABLE( data, sz );
2112
	ADVANCE_RING();
2085
	ADVANCE_RING();
2113
2086
2114
	cmdbuf->buf += sz * sizeof(int);
2087
	cmdbuf->buf += sz * sizeof(int);
Lines 2122-2128 Link Here
2122
	drm_radeon_cmd_buffer_t *cmdbuf )
2095
	drm_radeon_cmd_buffer_t *cmdbuf )
2123
{
2096
{
2124
	int sz = header.scalars.count;
2097
	int sz = header.scalars.count;
2125
	int __user *data = (int __user *)cmdbuf->buf;
2126
	int start = header.scalars.offset;
2098
	int start = header.scalars.offset;
2127
	int stride = header.scalars.stride;
2099
	int stride = header.scalars.stride;
2128
	RING_LOCALS;
2100
	RING_LOCALS;
Lines 2131-2137 Link Here
2131
	OUT_RING( CP_PACKET0( RADEON_SE_TCL_SCALAR_INDX_REG, 0 ) );
2103
	OUT_RING( CP_PACKET0( RADEON_SE_TCL_SCALAR_INDX_REG, 0 ) );
2132
	OUT_RING( start | (stride << RADEON_SCAL_INDX_DWORD_STRIDE_SHIFT));
2104
	OUT_RING( start | (stride << RADEON_SCAL_INDX_DWORD_STRIDE_SHIFT));
2133
	OUT_RING( CP_PACKET0_TABLE( RADEON_SE_TCL_SCALAR_DATA_REG, sz-1 ) );
2105
	OUT_RING( CP_PACKET0_TABLE( RADEON_SE_TCL_SCALAR_DATA_REG, sz-1 ) );
2134
	OUT_RING_USER_TABLE( data, sz );
2106
	OUT_RING_TABLE( cmdbuf->buf, sz );
2135
	ADVANCE_RING();
2107
	ADVANCE_RING();
2136
	cmdbuf->buf += sz * sizeof(int);
2108
	cmdbuf->buf += sz * sizeof(int);
2137
	cmdbuf->bufsz -= sz * sizeof(int);
2109
	cmdbuf->bufsz -= sz * sizeof(int);
Lines 2146-2152 Link Here
2146
	drm_radeon_cmd_buffer_t *cmdbuf )
2118
	drm_radeon_cmd_buffer_t *cmdbuf )
2147
{
2119
{
2148
	int sz = header.scalars.count;
2120
	int sz = header.scalars.count;
2149
	int __user *data = (int __user *)cmdbuf->buf;
2150
	int start = ((unsigned int)header.scalars.offset) + 0x100;
2121
	int start = ((unsigned int)header.scalars.offset) + 0x100;
2151
	int stride = header.scalars.stride;
2122
	int stride = header.scalars.stride;
2152
	RING_LOCALS;
2123
	RING_LOCALS;
Lines 2155-2161 Link Here
2155
	OUT_RING( CP_PACKET0( RADEON_SE_TCL_SCALAR_INDX_REG, 0 ) );
2126
	OUT_RING( CP_PACKET0( RADEON_SE_TCL_SCALAR_INDX_REG, 0 ) );
2156
	OUT_RING( start | (stride << RADEON_SCAL_INDX_DWORD_STRIDE_SHIFT));
2127
	OUT_RING( start | (stride << RADEON_SCAL_INDX_DWORD_STRIDE_SHIFT));
2157
	OUT_RING( CP_PACKET0_TABLE( RADEON_SE_TCL_SCALAR_DATA_REG, sz-1 ) );
2128
	OUT_RING( CP_PACKET0_TABLE( RADEON_SE_TCL_SCALAR_DATA_REG, sz-1 ) );
2158
	OUT_RING_USER_TABLE( data, sz );
2129
	OUT_RING_TABLE( cmdbuf->buf, sz );
2159
	ADVANCE_RING();
2130
	ADVANCE_RING();
2160
	cmdbuf->buf += sz * sizeof(int);
2131
	cmdbuf->buf += sz * sizeof(int);
2161
	cmdbuf->bufsz -= sz * sizeof(int);
2132
	cmdbuf->bufsz -= sz * sizeof(int);
Lines 2168-2174 Link Here
2168
	drm_radeon_cmd_buffer_t *cmdbuf )
2139
	drm_radeon_cmd_buffer_t *cmdbuf )
2169
{
2140
{
2170
	int sz = header.vectors.count;
2141
	int sz = header.vectors.count;
2171
	int __user *data = (int __user *)cmdbuf->buf;
2172
	int start = header.vectors.offset;
2142
	int start = header.vectors.offset;
2173
	int stride = header.vectors.stride;
2143
	int stride = header.vectors.stride;
2174
	RING_LOCALS;
2144
	RING_LOCALS;
Lines 2177-2183 Link Here
2177
	OUT_RING( CP_PACKET0( RADEON_SE_TCL_VECTOR_INDX_REG, 0 ) );
2147
	OUT_RING( CP_PACKET0( RADEON_SE_TCL_VECTOR_INDX_REG, 0 ) );
2178
	OUT_RING( start | (stride << RADEON_VEC_INDX_OCTWORD_STRIDE_SHIFT));
2148
	OUT_RING( start | (stride << RADEON_VEC_INDX_OCTWORD_STRIDE_SHIFT));
2179
	OUT_RING( CP_PACKET0_TABLE( RADEON_SE_TCL_VECTOR_DATA_REG, (sz-1) ) );
2149
	OUT_RING( CP_PACKET0_TABLE( RADEON_SE_TCL_VECTOR_DATA_REG, (sz-1) ) );
2180
	OUT_RING_USER_TABLE( data, sz );
2150
	OUT_RING_TABLE( cmdbuf->buf, sz );
2181
	ADVANCE_RING();
2151
	ADVANCE_RING();
2182
2152
2183
	cmdbuf->buf += sz * sizeof(int);
2153
	cmdbuf->buf += sz * sizeof(int);
Lines 2192-2198 Link Here
2192
{
2162
{
2193
	drm_radeon_private_t *dev_priv = dev->dev_private;
2163
	drm_radeon_private_t *dev_priv = dev->dev_private;
2194
	unsigned int cmdsz;
2164
	unsigned int cmdsz;
2195
	int __user *cmd = (int __user *)cmdbuf->buf;
2196
	int ret;
2165
	int ret;
2197
	RING_LOCALS;
2166
	RING_LOCALS;
2198
2167
Lines 2205-2211 Link Here
2205
	}
2174
	}
2206
2175
2207
	BEGIN_RING( cmdsz );
2176
	BEGIN_RING( cmdsz );
2208
	OUT_RING_USER_TABLE( cmd, cmdsz );
2177
	OUT_RING_TABLE( cmdbuf->buf, cmdsz );
2209
	ADVANCE_RING();
2178
	ADVANCE_RING();
2210
2179
2211
	cmdbuf->buf += cmdsz * 4;
2180
	cmdbuf->buf += cmdsz * 4;
Lines 2222-2228 Link Here
2222
	drm_radeon_private_t *dev_priv = dev->dev_private;
2191
	drm_radeon_private_t *dev_priv = dev->dev_private;
2223
	drm_clip_rect_t box;
2192
	drm_clip_rect_t box;
2224
	unsigned int cmdsz;
2193
	unsigned int cmdsz;
2225
	int __user *cmd = (int __user *)cmdbuf->buf;
2226
	int ret;
2194
	int ret;
2227
	drm_clip_rect_t __user *boxes = cmdbuf->boxes;
2195
	drm_clip_rect_t __user *boxes = cmdbuf->boxes;
2228
	int i = 0;
2196
	int i = 0;
Lines 2241-2247 Link Here
2241
2209
2242
	do {
2210
	do {
2243
		if ( i < cmdbuf->nbox ) {
2211
		if ( i < cmdbuf->nbox ) {
2244
			if (DRM_COPY_FROM_USER_UNCHECKED( &box, &boxes[i], sizeof(box) ))
2212
			if (DRM_COPY_FROM_USER( &box, &boxes[i], sizeof(box) ))
2245
				return DRM_ERR(EFAULT);
2213
				return DRM_ERR(EFAULT);
2246
			/* FIXME The second and subsequent times round
2214
			/* FIXME The second and subsequent times round
2247
			 * this loop, send a WAIT_UNTIL_3D_IDLE before
2215
			 * this loop, send a WAIT_UNTIL_3D_IDLE before
Lines 2264-2270 Link Here
2264
		}
2232
		}
2265
		
2233
		
2266
		BEGIN_RING( cmdsz );
2234
		BEGIN_RING( cmdsz );
2267
		OUT_RING_USER_TABLE( cmd, cmdsz );
2235
		OUT_RING_TABLE( cmdbuf->buf, cmdsz );
2268
		ADVANCE_RING();
2236
		ADVANCE_RING();
2269
2237
2270
	} while ( ++i < cmdbuf->nbox );
2238
	} while ( ++i < cmdbuf->nbox );
Lines 2317-2323 Link Here
2317
	int idx;
2285
	int idx;
2318
	drm_radeon_cmd_buffer_t cmdbuf;
2286
	drm_radeon_cmd_buffer_t cmdbuf;
2319
	drm_radeon_cmd_header_t header;
2287
	drm_radeon_cmd_header_t header;
2320
	int orig_nbox;
2288
	int orig_nbox, orig_bufsz;
2289
	char *kbuf=NULL;
2321
2290
2322
	LOCK_TEST_WITH_RETURN( dev, filp );
2291
	LOCK_TEST_WITH_RETURN( dev, filp );
2323
2292
Lines 2334-2357 Link Here
2334
	RING_SPACE_TEST_WITH_RETURN( dev_priv );
2303
	RING_SPACE_TEST_WITH_RETURN( dev_priv );
2335
	VB_AGE_TEST_WITH_RETURN( dev_priv );
2304
	VB_AGE_TEST_WITH_RETURN( dev_priv );
2336
2305
2306
	if (cmdbuf.bufsz > 64*1024 || cmdbuf.bufsz<0) {
2307
		return DRM_ERR(EINVAL);
2308
	}
2337
2309
2338
	if (DRM_VERIFYAREA_READ( cmdbuf.buf, cmdbuf.bufsz ))
2310
	/* Allocate an in-kernel area and copy in the cmdbuf.  Do this to avoid
2339
		return DRM_ERR(EFAULT);
2311
	 * races between checking values and using those values in other code,
2340
2312
	 * and simply to avoid a lot of function calls to copy in data.
2341
	if (cmdbuf.nbox &&
2313
	 */
2342
	    DRM_VERIFYAREA_READ(cmdbuf.boxes, 
2314
	orig_bufsz = cmdbuf.bufsz;
2343
			 cmdbuf.nbox * sizeof(drm_clip_rect_t)))
2315
	if (orig_bufsz != 0) {
2344
		return DRM_ERR(EFAULT);
2316
		kbuf = DRM_MALLOC(cmdbuf.bufsz);
2317
		if (kbuf == NULL)
2318
			return DRM_ERR(ENOMEM);
2319
		if (DRM_COPY_FROM_USER(kbuf, cmdbuf.buf, cmdbuf.bufsz))
2320
			return DRM_ERR(EFAULT);
2321
		cmdbuf.buf = kbuf;
2322
	}
2345
2323
2346
	orig_nbox = cmdbuf.nbox;
2324
	orig_nbox = cmdbuf.nbox;
2347
2325
2348
	while ( cmdbuf.bufsz >= sizeof(header) ) {
2326
	while ( cmdbuf.bufsz >= sizeof(header) ) {
2349
		
2350
		if (DRM_GET_USER_UNCHECKED( header.i, (int __user *)cmdbuf.buf )) {
2351
			DRM_ERROR("__get_user %p\n", cmdbuf.buf);
2352
			return DRM_ERR(EFAULT);
2353
		}
2354
2327
2328
		header.i = *(int *)cmdbuf.buf;
2355
		cmdbuf.buf += sizeof(header);
2329
		cmdbuf.buf += sizeof(header);
2356
		cmdbuf.bufsz -= sizeof(header);
2330
		cmdbuf.bufsz -= sizeof(header);
2357
2331
Lines 2360-2366 Link Here
2360
			DRM_DEBUG("RADEON_CMD_PACKET\n");
2334
			DRM_DEBUG("RADEON_CMD_PACKET\n");
2361
			if (radeon_emit_packets( dev_priv, filp_priv, header, &cmdbuf )) {
2335
			if (radeon_emit_packets( dev_priv, filp_priv, header, &cmdbuf )) {
2362
				DRM_ERROR("radeon_emit_packets failed\n");
2336
				DRM_ERROR("radeon_emit_packets failed\n");
2363
				return DRM_ERR(EINVAL);
2337
				goto err;
2364
			}
2338
			}
2365
			break;
2339
			break;
2366
2340
Lines 2368-2374 Link Here
2368
			DRM_DEBUG("RADEON_CMD_SCALARS\n");
2342
			DRM_DEBUG("RADEON_CMD_SCALARS\n");
2369
			if (radeon_emit_scalars( dev_priv, header, &cmdbuf )) {
2343
			if (radeon_emit_scalars( dev_priv, header, &cmdbuf )) {
2370
				DRM_ERROR("radeon_emit_scalars failed\n");
2344
				DRM_ERROR("radeon_emit_scalars failed\n");
2371
				return DRM_ERR(EINVAL);
2345
				goto err;
2372
			}
2346
			}
2373
			break;
2347
			break;
2374
2348
Lines 2376-2382 Link Here
2376
			DRM_DEBUG("RADEON_CMD_VECTORS\n");
2350
			DRM_DEBUG("RADEON_CMD_VECTORS\n");
2377
			if (radeon_emit_vectors( dev_priv, header, &cmdbuf )) {
2351
			if (radeon_emit_vectors( dev_priv, header, &cmdbuf )) {
2378
				DRM_ERROR("radeon_emit_vectors failed\n");
2352
				DRM_ERROR("radeon_emit_vectors failed\n");
2379
				return DRM_ERR(EINVAL);
2353
				goto err;
2380
			}
2354
			}
2381
			break;
2355
			break;
2382
2356
Lines 2386-2399 Link Here
2386
			if ( idx < 0 || idx >= dma->buf_count ) {
2360
			if ( idx < 0 || idx >= dma->buf_count ) {
2387
				DRM_ERROR( "buffer index %d (of %d max)\n",
2361
				DRM_ERROR( "buffer index %d (of %d max)\n",
2388
					   idx, dma->buf_count - 1 );
2362
					   idx, dma->buf_count - 1 );
2389
				return DRM_ERR(EINVAL);
2363
				goto err;
2390
			}
2364
			}
2391
2365
2392
			buf = dma->buflist[idx];
2366
			buf = dma->buflist[idx];
2393
			if ( buf->filp != filp || buf->pending ) {
2367
			if ( buf->filp != filp || buf->pending ) {
2394
				DRM_ERROR( "bad buffer %p %p %d\n",
2368
				DRM_ERROR( "bad buffer %p %p %d\n",
2395
					   buf->filp, filp, buf->pending);
2369
					   buf->filp, filp, buf->pending);
2396
				return DRM_ERR(EINVAL);
2370
				goto err;
2397
			}
2371
			}
2398
2372
2399
			radeon_cp_discard_buffer( dev, buf );
2373
			radeon_cp_discard_buffer( dev, buf );
Lines 2403-2409 Link Here
2403
			DRM_DEBUG("RADEON_CMD_PACKET3\n");
2377
			DRM_DEBUG("RADEON_CMD_PACKET3\n");
2404
			if (radeon_emit_packet3( dev, filp_priv, &cmdbuf )) {
2378
			if (radeon_emit_packet3( dev, filp_priv, &cmdbuf )) {
2405
				DRM_ERROR("radeon_emit_packet3 failed\n");
2379
				DRM_ERROR("radeon_emit_packet3 failed\n");
2406
				return DRM_ERR(EINVAL);
2380
				goto err;
2407
			}
2381
			}
2408
			break;
2382
			break;
2409
2383
Lines 2411-2417 Link Here
2411
			DRM_DEBUG("RADEON_CMD_PACKET3_CLIP\n");
2385
			DRM_DEBUG("RADEON_CMD_PACKET3_CLIP\n");
2412
			if (radeon_emit_packet3_cliprect( dev, filp_priv, &cmdbuf, orig_nbox )) {
2386
			if (radeon_emit_packet3_cliprect( dev, filp_priv, &cmdbuf, orig_nbox )) {
2413
				DRM_ERROR("radeon_emit_packet3_clip failed\n");
2387
				DRM_ERROR("radeon_emit_packet3_clip failed\n");
2414
				return DRM_ERR(EINVAL);
2388
				goto err;
2415
			}
2389
			}
2416
			break;
2390
			break;
2417
2391
Lines 2419-2425 Link Here
2419
			DRM_DEBUG("RADEON_CMD_SCALARS2\n");
2393
			DRM_DEBUG("RADEON_CMD_SCALARS2\n");
2420
			if (radeon_emit_scalars2( dev_priv, header, &cmdbuf )) {
2394
			if (radeon_emit_scalars2( dev_priv, header, &cmdbuf )) {
2421
				DRM_ERROR("radeon_emit_scalars2 failed\n");
2395
				DRM_ERROR("radeon_emit_scalars2 failed\n");
2422
				return DRM_ERR(EINVAL);
2396
				goto err;
2423
			}
2397
			}
2424
			break;
2398
			break;
2425
2399
Lines 2427-2447 Link Here
2427
			DRM_DEBUG("RADEON_CMD_WAIT\n");
2401
			DRM_DEBUG("RADEON_CMD_WAIT\n");
2428
			if (radeon_emit_wait( dev, header.wait.flags )) {
2402
			if (radeon_emit_wait( dev, header.wait.flags )) {
2429
				DRM_ERROR("radeon_emit_wait failed\n");
2403
				DRM_ERROR("radeon_emit_wait failed\n");
2430
				return DRM_ERR(EINVAL);
2404
				goto err;
2431
			}
2405
			}
2432
			break;
2406
			break;
2433
		default:
2407
		default:
2434
			DRM_ERROR("bad cmd_type %d at %p\n", 
2408
			DRM_ERROR("bad cmd_type %d at %p\n", 
2435
				  header.header.cmd_type,
2409
				  header.header.cmd_type,
2436
				  cmdbuf.buf - sizeof(header));
2410
				  cmdbuf.buf - sizeof(header));
2437
			return DRM_ERR(EINVAL);
2411
			goto err;
2438
		}
2412
		}
2439
	}
2413
	}
2440
2414
2415
	if (orig_bufsz != 0)
2416
		DRM_FREE(kbuf, orig_bufsz);
2441
2417
2442
	DRM_DEBUG("DONE\n");
2418
	DRM_DEBUG("DONE\n");
2443
	COMMIT_RING();
2419
	COMMIT_RING();
2444
	return 0;
2420
	return 0;
2421
2422
err:
2423
	if (orig_bufsz != 0)
2424
		DRM_FREE(kbuf, orig_bufsz);
2425
	return DRM_ERR(EINVAL);
2445
}
2426
}
2446
2427
2447
2428

Return to bug 81294