diff options
author | Marek Olšák <maraeo@gmail.com> | 2011-02-13 19:01:10 -0500 |
---|---|---|
committer | Dave Airlie <airlied@redhat.com> | 2011-02-13 19:12:14 -0500 |
commit | fff1ce4dc6113b6fdc4e3a815ca5fd229408f8ef (patch) | |
tree | 67b3cf58e6b1a23a81bd45b1c98455020f6db248 /drivers/gpu/drm/radeon/r100.c | |
parent | 501834349e872ed4115eea3beef65ca9eeb5528e (diff) |
drm/radeon/kms: check AA resolve registers on r300
This is an important security fix because we allowed arbitrary values
to be passed to AARESOLVE_OFFSET. This also puts the right buffer address
in the register.
Signed-off-by: Marek Olšák <maraeo@gmail.com>
Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/radeon/r100.c')
-rw-r--r-- | drivers/gpu/drm/radeon/r100.c | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index fdf4bc67ae58..56deae5bf02e 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c | |||
@@ -3381,6 +3381,26 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track) | |||
3381 | } | 3381 | } |
3382 | track->zb_dirty = false; | 3382 | track->zb_dirty = false; |
3383 | 3383 | ||
3384 | if (track->aa_dirty && track->aaresolve) { | ||
3385 | if (track->aa.robj == NULL) { | ||
3386 | DRM_ERROR("[drm] No buffer for AA resolve buffer %d !\n", i); | ||
3387 | return -EINVAL; | ||
3388 | } | ||
3389 | /* I believe the format comes from colorbuffer0. */ | ||
3390 | size = track->aa.pitch * track->cb[0].cpp * track->maxy; | ||
3391 | size += track->aa.offset; | ||
3392 | if (size > radeon_bo_size(track->aa.robj)) { | ||
3393 | DRM_ERROR("[drm] Buffer too small for AA resolve buffer %d " | ||
3394 | "(need %lu have %lu) !\n", i, size, | ||
3395 | radeon_bo_size(track->aa.robj)); | ||
3396 | DRM_ERROR("[drm] AA resolve buffer %d (%u %u %u %u)\n", | ||
3397 | i, track->aa.pitch, track->cb[0].cpp, | ||
3398 | track->aa.offset, track->maxy); | ||
3399 | return -EINVAL; | ||
3400 | } | ||
3401 | } | ||
3402 | track->aa_dirty = false; | ||
3403 | |||
3384 | prim_walk = (track->vap_vf_cntl >> 4) & 0x3; | 3404 | prim_walk = (track->vap_vf_cntl >> 4) & 0x3; |
3385 | if (track->vap_vf_cntl & (1 << 14)) { | 3405 | if (track->vap_vf_cntl & (1 << 14)) { |
3386 | nverts = track->vap_alt_nverts; | 3406 | nverts = track->vap_alt_nverts; |
@@ -3455,6 +3475,7 @@ void r100_cs_track_clear(struct radeon_device *rdev, struct r100_cs_track *track | |||
3455 | track->cb_dirty = true; | 3475 | track->cb_dirty = true; |
3456 | track->zb_dirty = true; | 3476 | track->zb_dirty = true; |
3457 | track->tex_dirty = true; | 3477 | track->tex_dirty = true; |
3478 | track->aa_dirty = true; | ||
3458 | 3479 | ||
3459 | if (rdev->family < CHIP_R300) { | 3480 | if (rdev->family < CHIP_R300) { |
3460 | track->num_cb = 1; | 3481 | track->num_cb = 1; |
@@ -3469,6 +3490,8 @@ void r100_cs_track_clear(struct radeon_device *rdev, struct r100_cs_track *track | |||
3469 | track->num_texture = 16; | 3490 | track->num_texture = 16; |
3470 | track->maxy = 4096; | 3491 | track->maxy = 4096; |
3471 | track->separate_cube = 0; | 3492 | track->separate_cube = 0; |
3493 | track->aaresolve = true; | ||
3494 | track->aa.robj = NULL; | ||
3472 | } | 3495 | } |
3473 | 3496 | ||
3474 | for (i = 0; i < track->num_cb; i++) { | 3497 | for (i = 0; i < track->num_cb; i++) { |