Skip to content

Commit

Permalink
drm/radeon/kms: check AA resolve registers on r300
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Marek Olšák authored and Dave Airlie committed Feb 14, 2011
1 parent 5018343 commit fff1ce4
Show file tree
Hide file tree
Showing 8 changed files with 49 additions and 13 deletions.
23 changes: 23 additions & 0 deletions drivers/gpu/drm/radeon/r100.c
Original file line number Diff line number Diff line change
Expand Up @@ -3381,6 +3381,26 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track)
}
track->zb_dirty = false;

if (track->aa_dirty && track->aaresolve) {
if (track->aa.robj == NULL) {
DRM_ERROR("[drm] No buffer for AA resolve buffer %d !\n", i);
return -EINVAL;
}
/* I believe the format comes from colorbuffer0. */
size = track->aa.pitch * track->cb[0].cpp * track->maxy;
size += track->aa.offset;
if (size > radeon_bo_size(track->aa.robj)) {
DRM_ERROR("[drm] Buffer too small for AA resolve buffer %d "
"(need %lu have %lu) !\n", i, size,
radeon_bo_size(track->aa.robj));
DRM_ERROR("[drm] AA resolve buffer %d (%u %u %u %u)\n",
i, track->aa.pitch, track->cb[0].cpp,
track->aa.offset, track->maxy);
return -EINVAL;
}
}
track->aa_dirty = false;

prim_walk = (track->vap_vf_cntl >> 4) & 0x3;
if (track->vap_vf_cntl & (1 << 14)) {
nverts = track->vap_alt_nverts;
Expand Down Expand Up @@ -3455,6 +3475,7 @@ void r100_cs_track_clear(struct radeon_device *rdev, struct r100_cs_track *track
track->cb_dirty = true;
track->zb_dirty = true;
track->tex_dirty = true;
track->aa_dirty = true;

if (rdev->family < CHIP_R300) {
track->num_cb = 1;
Expand All @@ -3469,6 +3490,8 @@ void r100_cs_track_clear(struct radeon_device *rdev, struct r100_cs_track *track
track->num_texture = 16;
track->maxy = 4096;
track->separate_cube = 0;
track->aaresolve = true;
track->aa.robj = NULL;
}

for (i = 0; i < track->num_cb; i++) {
Expand Down
4 changes: 3 additions & 1 deletion drivers/gpu/drm/radeon/r100_track.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,15 +66,17 @@ struct r100_cs_track {
struct r100_cs_track_array arrays[11];
struct r100_cs_track_cb cb[R300_MAX_CB];
struct r100_cs_track_cb zb;
struct r100_cs_track_cb aa;
struct r100_cs_track_texture textures[R300_TRACK_MAX_TEXTURE];
bool z_enabled;
bool separate_cube;
bool zb_cb_clear;
bool blend_read_enable;

bool cb_dirty;
bool zb_dirty;
bool tex_dirty;
bool aa_dirty;
bool aaresolve;
};

int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track);
Expand Down
21 changes: 21 additions & 0 deletions drivers/gpu/drm/radeon/r300.c
Original file line number Diff line number Diff line change
Expand Up @@ -1104,6 +1104,27 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
track->blend_read_enable = !!(idx_value & (1 << 2));
track->cb_dirty = true;
break;
case R300_RB3D_AARESOLVE_OFFSET:
r = r100_cs_packet_next_reloc(p, &reloc);
if (r) {
DRM_ERROR("No reloc for ib[%d]=0x%04X\n",
idx, reg);
r100_cs_dump_packet(p, pkt);
return r;
}
track->aa.robj = reloc->robj;
track->aa.offset = idx_value;
track->aa_dirty = true;
ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset);
break;
case R300_RB3D_AARESOLVE_PITCH:
track->aa.pitch = idx_value & 0x3FFE;
track->aa_dirty = true;
break;
case R300_RB3D_AARESOLVE_CTL:
track->aaresolve = idx_value & 0x1;
track->aa_dirty = true;
break;
case 0x4f30: /* ZB_MASK_OFFSET */
case 0x4f34: /* ZB_ZMASK_PITCH */
case 0x4f44: /* ZB_HIZ_OFFSET */
Expand Down
2 changes: 2 additions & 0 deletions drivers/gpu/drm/radeon/r300_reg.h
Original file line number Diff line number Diff line change
Expand Up @@ -1371,6 +1371,8 @@
#define R300_RB3D_COLORPITCH2 0x4E40 /* GUESS */
#define R300_RB3D_COLORPITCH3 0x4E44 /* GUESS */

#define R300_RB3D_AARESOLVE_OFFSET 0x4E80
#define R300_RB3D_AARESOLVE_PITCH 0x4E84
#define R300_RB3D_AARESOLVE_CTL 0x4E88
/* gap */

Expand Down
3 changes: 0 additions & 3 deletions drivers/gpu/drm/radeon/reg_srcs/r300
Original file line number Diff line number Diff line change
Expand Up @@ -704,9 +704,6 @@ r300 0x4f60
0x4E74 RB3D_CMASK_WRINDEX
0x4E78 RB3D_CMASK_DWORD
0x4E7C RB3D_CMASK_RDINDEX
0x4E80 RB3D_AARESOLVE_OFFSET
0x4E84 RB3D_AARESOLVE_PITCH
0x4E88 RB3D_AARESOLVE_CTL
0x4EA0 RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD
0x4EA4 RB3D_DISCARD_SRC_PIXEL_GTE_THRESHOLD
0x4F04 ZB_ZSTENCILCNTL
Expand Down
3 changes: 0 additions & 3 deletions drivers/gpu/drm/radeon/reg_srcs/r420
Original file line number Diff line number Diff line change
Expand Up @@ -770,9 +770,6 @@ r420 0x4f60
0x4E74 RB3D_CMASK_WRINDEX
0x4E78 RB3D_CMASK_DWORD
0x4E7C RB3D_CMASK_RDINDEX
0x4E80 RB3D_AARESOLVE_OFFSET
0x4E84 RB3D_AARESOLVE_PITCH
0x4E88 RB3D_AARESOLVE_CTL
0x4EA0 RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD
0x4EA4 RB3D_DISCARD_SRC_PIXEL_GTE_THRESHOLD
0x4F04 ZB_ZSTENCILCNTL
Expand Down
3 changes: 0 additions & 3 deletions drivers/gpu/drm/radeon/reg_srcs/rs600
Original file line number Diff line number Diff line change
Expand Up @@ -770,9 +770,6 @@ rs600 0x6d40
0x4E74 RB3D_CMASK_WRINDEX
0x4E78 RB3D_CMASK_DWORD
0x4E7C RB3D_CMASK_RDINDEX
0x4E80 RB3D_AARESOLVE_OFFSET
0x4E84 RB3D_AARESOLVE_PITCH
0x4E88 RB3D_AARESOLVE_CTL
0x4EA0 RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD
0x4EA4 RB3D_DISCARD_SRC_PIXEL_GTE_THRESHOLD
0x4F04 ZB_ZSTENCILCNTL
Expand Down
3 changes: 0 additions & 3 deletions drivers/gpu/drm/radeon/reg_srcs/rv515
Original file line number Diff line number Diff line change
Expand Up @@ -481,9 +481,6 @@ rv515 0x6d40
0x4E74 RB3D_CMASK_WRINDEX
0x4E78 RB3D_CMASK_DWORD
0x4E7C RB3D_CMASK_RDINDEX
0x4E80 RB3D_AARESOLVE_OFFSET
0x4E84 RB3D_AARESOLVE_PITCH
0x4E88 RB3D_AARESOLVE_CTL
0x4EA0 RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD
0x4EA4 RB3D_DISCARD_SRC_PIXEL_GTE_THRESHOLD
0x4EF8 RB3D_CONSTANT_COLOR_AR
Expand Down

0 comments on commit fff1ce4

Please sign in to comment.