Commit fff1ce4d authored by Marek Olšák's avatar Marek Olšák Committed by Dave Airlie

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: default avatarMarek Olšák <maraeo@gmail.com>
Signed-off-by: default avatarDave Airlie <airlied@redhat.com>
parent 50183434
...@@ -3381,6 +3381,26 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track) ...@@ -3381,6 +3381,26 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track)
} }
track->zb_dirty = false; 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; prim_walk = (track->vap_vf_cntl >> 4) & 0x3;
if (track->vap_vf_cntl & (1 << 14)) { if (track->vap_vf_cntl & (1 << 14)) {
nverts = track->vap_alt_nverts; nverts = track->vap_alt_nverts;
...@@ -3455,6 +3475,7 @@ void r100_cs_track_clear(struct radeon_device *rdev, struct r100_cs_track *track ...@@ -3455,6 +3475,7 @@ void r100_cs_track_clear(struct radeon_device *rdev, struct r100_cs_track *track
track->cb_dirty = true; track->cb_dirty = true;
track->zb_dirty = true; track->zb_dirty = true;
track->tex_dirty = true; track->tex_dirty = true;
track->aa_dirty = true;
if (rdev->family < CHIP_R300) { if (rdev->family < CHIP_R300) {
track->num_cb = 1; track->num_cb = 1;
...@@ -3469,6 +3490,8 @@ void r100_cs_track_clear(struct radeon_device *rdev, struct r100_cs_track *track ...@@ -3469,6 +3490,8 @@ void r100_cs_track_clear(struct radeon_device *rdev, struct r100_cs_track *track
track->num_texture = 16; track->num_texture = 16;
track->maxy = 4096; track->maxy = 4096;
track->separate_cube = 0; track->separate_cube = 0;
track->aaresolve = true;
track->aa.robj = NULL;
} }
for (i = 0; i < track->num_cb; i++) { for (i = 0; i < track->num_cb; i++) {
......
...@@ -66,15 +66,17 @@ struct r100_cs_track { ...@@ -66,15 +66,17 @@ struct r100_cs_track {
struct r100_cs_track_array arrays[11]; struct r100_cs_track_array arrays[11];
struct r100_cs_track_cb cb[R300_MAX_CB]; struct r100_cs_track_cb cb[R300_MAX_CB];
struct r100_cs_track_cb zb; struct r100_cs_track_cb zb;
struct r100_cs_track_cb aa;
struct r100_cs_track_texture textures[R300_TRACK_MAX_TEXTURE]; struct r100_cs_track_texture textures[R300_TRACK_MAX_TEXTURE];
bool z_enabled; bool z_enabled;
bool separate_cube; bool separate_cube;
bool zb_cb_clear; bool zb_cb_clear;
bool blend_read_enable; bool blend_read_enable;
bool cb_dirty; bool cb_dirty;
bool zb_dirty; bool zb_dirty;
bool tex_dirty; bool tex_dirty;
bool aa_dirty;
bool aaresolve;
}; };
int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track); int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track);
......
...@@ -1104,6 +1104,27 @@ static int r300_packet0_check(struct radeon_cs_parser *p, ...@@ -1104,6 +1104,27 @@ static int r300_packet0_check(struct radeon_cs_parser *p,
track->blend_read_enable = !!(idx_value & (1 << 2)); track->blend_read_enable = !!(idx_value & (1 << 2));
track->cb_dirty = true; track->cb_dirty = true;
break; 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 0x4f30: /* ZB_MASK_OFFSET */
case 0x4f34: /* ZB_ZMASK_PITCH */ case 0x4f34: /* ZB_ZMASK_PITCH */
case 0x4f44: /* ZB_HIZ_OFFSET */ case 0x4f44: /* ZB_HIZ_OFFSET */
......
...@@ -1371,6 +1371,8 @@ ...@@ -1371,6 +1371,8 @@
#define R300_RB3D_COLORPITCH2 0x4E40 /* GUESS */ #define R300_RB3D_COLORPITCH2 0x4E40 /* GUESS */
#define R300_RB3D_COLORPITCH3 0x4E44 /* 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 #define R300_RB3D_AARESOLVE_CTL 0x4E88
/* gap */ /* gap */
......
...@@ -704,9 +704,6 @@ r300 0x4f60 ...@@ -704,9 +704,6 @@ r300 0x4f60
0x4E74 RB3D_CMASK_WRINDEX 0x4E74 RB3D_CMASK_WRINDEX
0x4E78 RB3D_CMASK_DWORD 0x4E78 RB3D_CMASK_DWORD
0x4E7C RB3D_CMASK_RDINDEX 0x4E7C RB3D_CMASK_RDINDEX
0x4E80 RB3D_AARESOLVE_OFFSET
0x4E84 RB3D_AARESOLVE_PITCH
0x4E88 RB3D_AARESOLVE_CTL
0x4EA0 RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD 0x4EA0 RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD
0x4EA4 RB3D_DISCARD_SRC_PIXEL_GTE_THRESHOLD 0x4EA4 RB3D_DISCARD_SRC_PIXEL_GTE_THRESHOLD
0x4F04 ZB_ZSTENCILCNTL 0x4F04 ZB_ZSTENCILCNTL
......
...@@ -770,9 +770,6 @@ r420 0x4f60 ...@@ -770,9 +770,6 @@ r420 0x4f60
0x4E74 RB3D_CMASK_WRINDEX 0x4E74 RB3D_CMASK_WRINDEX
0x4E78 RB3D_CMASK_DWORD 0x4E78 RB3D_CMASK_DWORD
0x4E7C RB3D_CMASK_RDINDEX 0x4E7C RB3D_CMASK_RDINDEX
0x4E80 RB3D_AARESOLVE_OFFSET
0x4E84 RB3D_AARESOLVE_PITCH
0x4E88 RB3D_AARESOLVE_CTL
0x4EA0 RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD 0x4EA0 RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD
0x4EA4 RB3D_DISCARD_SRC_PIXEL_GTE_THRESHOLD 0x4EA4 RB3D_DISCARD_SRC_PIXEL_GTE_THRESHOLD
0x4F04 ZB_ZSTENCILCNTL 0x4F04 ZB_ZSTENCILCNTL
......
...@@ -770,9 +770,6 @@ rs600 0x6d40 ...@@ -770,9 +770,6 @@ rs600 0x6d40
0x4E74 RB3D_CMASK_WRINDEX 0x4E74 RB3D_CMASK_WRINDEX
0x4E78 RB3D_CMASK_DWORD 0x4E78 RB3D_CMASK_DWORD
0x4E7C RB3D_CMASK_RDINDEX 0x4E7C RB3D_CMASK_RDINDEX
0x4E80 RB3D_AARESOLVE_OFFSET
0x4E84 RB3D_AARESOLVE_PITCH
0x4E88 RB3D_AARESOLVE_CTL
0x4EA0 RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD 0x4EA0 RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD
0x4EA4 RB3D_DISCARD_SRC_PIXEL_GTE_THRESHOLD 0x4EA4 RB3D_DISCARD_SRC_PIXEL_GTE_THRESHOLD
0x4F04 ZB_ZSTENCILCNTL 0x4F04 ZB_ZSTENCILCNTL
......
...@@ -481,9 +481,6 @@ rv515 0x6d40 ...@@ -481,9 +481,6 @@ rv515 0x6d40
0x4E74 RB3D_CMASK_WRINDEX 0x4E74 RB3D_CMASK_WRINDEX
0x4E78 RB3D_CMASK_DWORD 0x4E78 RB3D_CMASK_DWORD
0x4E7C RB3D_CMASK_RDINDEX 0x4E7C RB3D_CMASK_RDINDEX
0x4E80 RB3D_AARESOLVE_OFFSET
0x4E84 RB3D_AARESOLVE_PITCH
0x4E88 RB3D_AARESOLVE_CTL
0x4EA0 RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD 0x4EA0 RB3D_DISCARD_SRC_PIXEL_LTE_THRESHOLD
0x4EA4 RB3D_DISCARD_SRC_PIXEL_GTE_THRESHOLD 0x4EA4 RB3D_DISCARD_SRC_PIXEL_GTE_THRESHOLD
0x4EF8 RB3D_CONSTANT_COLOR_AR 0x4EF8 RB3D_CONSTANT_COLOR_AR
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment