Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+23 −0
Original line number Diff line number Diff line
@@ -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;
@@ -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;
@@ -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++) {
+3 −1
Original line number Diff line number Diff line
@@ -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);
+21 −0
Original line number Diff line number Diff line
@@ -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 */
+2 −0
Original line number Diff line number Diff line
@@ -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 */

+0 −3
Original line number Diff line number Diff line
@@ -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
Loading