Message ID | 20110330135826.2C533F89E0@sepang.rtg.net |
---|---|
State | New |
Headers | show |
On 03/30/2011 03:58 PM, Tim Gardner wrote: > The following changes since commit dbf66000e09be0225011a7952defe1363965c014: > Dan Rosenberg (1): > irda: prevent integer underflow in IRLMP_ENUMDEVICES, CVE-2010-4529 > > are available in the git repository at: > > git://kernel.ubuntu.com/rtg/ubuntu-maverick.git master-next > > Dave Airlie (1): > drm/radeon: fix regression with AA resolve checking, CVE-2011-1016 > > Marek Olšák (1): > drm/radeon/kms: check AA resolve registers on r300, CVE-2011-1016 > > drivers/gpu/drm/radeon/r100.c | 24 ++++++++++++++++++++++++ > drivers/gpu/drm/radeon/r100_track.h | 3 +++ > drivers/gpu/drm/radeon/r300.c | 21 +++++++++++++++++++++ > drivers/gpu/drm/radeon/r300_reg.h | 2 ++ > drivers/gpu/drm/radeon/reg_srcs/r300 | 3 --- > drivers/gpu/drm/radeon/reg_srcs/r420 | 3 --- > drivers/gpu/drm/radeon/reg_srcs/rs600 | 3 --- > drivers/gpu/drm/radeon/reg_srcs/rv515 | 3 --- > 8 files changed, 50 insertions(+), 12 deletions(-) > > From 882940ccb39f9255f5bb5178e227d1f2bccf90b4 Mon Sep 17 00:00:00 2001 > From: =?UTF-8?q?Marek=20Ol=C5=A1=C3=A1k?= <maraeo@gmail.com> > Date: Tue, 29 Mar 2011 15:23:30 -0600 > Subject: [PATCH 1/2] drm/radeon/kms: check AA resolve registers on r300, CVE-2011-1016 > MIME-Version: 1.0 > Content-Type: text/plain; charset=UTF-8 > Content-Transfer-Encoding: 8bit > > BugLink: http://bugs.launchpad.net/bugs/745686 > > CVE-2011-1016 > > commit fff1ce4dc6113b6fdc4e3a815ca5fd229408f8ef upstream. > > 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> > [dannf: Backported to linux-2.6.32.y-drm33.z] > Signed-off-by: Tim Gardner <tim.gardner@canonical.com> > --- > drivers/gpu/drm/radeon/r100.c | 24 ++++++++++++++++++++++++ > drivers/gpu/drm/radeon/r100_track.h | 3 +++ > drivers/gpu/drm/radeon/r300.c | 21 +++++++++++++++++++++ > drivers/gpu/drm/radeon/r300_reg.h | 2 ++ > drivers/gpu/drm/radeon/reg_srcs/r300 | 3 --- > drivers/gpu/drm/radeon/reg_srcs/r420 | 3 --- > drivers/gpu/drm/radeon/reg_srcs/rs600 | 3 --- > drivers/gpu/drm/radeon/reg_srcs/rv515 | 3 --- > 8 files changed, 50 insertions(+), 12 deletions(-) > > diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c > index a3378ba..2a5c3ae 100644 > --- a/drivers/gpu/drm/radeon/r100.c > +++ b/drivers/gpu/drm/radeon/r100.c > @@ -3348,6 +3348,27 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track) > return -EINVAL; > } > } > + > + 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; > @@ -3413,6 +3434,7 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track) > void r100_cs_track_clear(struct radeon_device *rdev, struct r100_cs_track *track) > { > unsigned i, face; > + track->aa_dirty = true; > > if (rdev->family < CHIP_R300) { > track->num_cb = 1; > @@ -3427,6 +3449,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++) { > diff --git a/drivers/gpu/drm/radeon/r100_track.h b/drivers/gpu/drm/radeon/r100_track.h > index af65600..0584e26 100644 > --- a/drivers/gpu/drm/radeon/r100_track.h > +++ b/drivers/gpu/drm/radeon/r100_track.h > @@ -73,11 +73,14 @@ 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 aa_dirty; > + bool aaresolve; > }; > > int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track); > diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c > index 19a7ef7..76db6e9 100644 > --- a/drivers/gpu/drm/radeon/r300.c > +++ b/drivers/gpu/drm/radeon/r300.c > @@ -1056,6 +1056,27 @@ static int r300_packet0_check(struct radeon_cs_parser *p, > /* RB3D_BLENDCNTL */ > track->blend_read_enable = !!(idx_value & (1 << 2)); > 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 0x4be8: > /* valid register only on RV530 */ > if (p->rdev->family == CHIP_RV530) > diff --git a/drivers/gpu/drm/radeon/r300_reg.h b/drivers/gpu/drm/radeon/r300_reg.h > index 1a0d536..f0bce39 100644 > --- a/drivers/gpu/drm/radeon/r300_reg.h > +++ b/drivers/gpu/drm/radeon/r300_reg.h > @@ -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 */ > > diff --git a/drivers/gpu/drm/radeon/reg_srcs/r300 b/drivers/gpu/drm/radeon/reg_srcs/r300 > index 1e97b2d..0aa4aa0 100644 > --- a/drivers/gpu/drm/radeon/reg_srcs/r300 > +++ b/drivers/gpu/drm/radeon/reg_srcs/r300 > @@ -707,9 +707,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 > diff --git a/drivers/gpu/drm/radeon/reg_srcs/r420 b/drivers/gpu/drm/radeon/reg_srcs/r420 > index e958980..d2c4c22 100644 > --- a/drivers/gpu/drm/radeon/reg_srcs/r420 > +++ b/drivers/gpu/drm/radeon/reg_srcs/r420 > @@ -773,9 +773,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 > diff --git a/drivers/gpu/drm/radeon/reg_srcs/rs600 b/drivers/gpu/drm/radeon/reg_srcs/rs600 > index 83e8bc0..b51dfc6 100644 > --- a/drivers/gpu/drm/radeon/reg_srcs/rs600 > +++ b/drivers/gpu/drm/radeon/reg_srcs/rs600 > @@ -773,9 +773,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 > diff --git a/drivers/gpu/drm/radeon/reg_srcs/rv515 b/drivers/gpu/drm/radeon/reg_srcs/rv515 > index 1e46233..efae202 100644 > --- a/drivers/gpu/drm/radeon/reg_srcs/rv515 > +++ b/drivers/gpu/drm/radeon/reg_srcs/rv515 > @@ -468,9 +468,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 > Acked-by: Stefan Bader <stefan.bader@canonical.com>
On 03/30/2011 07:58 AM, Tim Gardner wrote: > The following changes since commit dbf66000e09be0225011a7952defe1363965c014: > Dan Rosenberg (1): > irda: prevent integer underflow in IRLMP_ENUMDEVICES, CVE-2010-4529 > > are available in the git repository at: > > git://kernel.ubuntu.com/rtg/ubuntu-maverick.git master-next > > Dave Airlie (1): > drm/radeon: fix regression with AA resolve checking, CVE-2011-1016 > > Marek Olšák (1): > drm/radeon/kms: check AA resolve registers on r300, CVE-2011-1016 > > drivers/gpu/drm/radeon/r100.c | 24 ++++++++++++++++++++++++ > drivers/gpu/drm/radeon/r100_track.h | 3 +++ > drivers/gpu/drm/radeon/r300.c | 21 +++++++++++++++++++++ > drivers/gpu/drm/radeon/r300_reg.h | 2 ++ > drivers/gpu/drm/radeon/reg_srcs/r300 | 3 --- > drivers/gpu/drm/radeon/reg_srcs/r420 | 3 --- > drivers/gpu/drm/radeon/reg_srcs/rs600 | 3 --- > drivers/gpu/drm/radeon/reg_srcs/rv515 | 3 --- > 8 files changed, 50 insertions(+), 12 deletions(-) > applied
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index a3378ba..2a5c3ae 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -3348,6 +3348,27 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track) return -EINVAL; } } + + 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; @@ -3413,6 +3434,7 @@ int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track) void r100_cs_track_clear(struct radeon_device *rdev, struct r100_cs_track *track) { unsigned i, face; + track->aa_dirty = true; if (rdev->family < CHIP_R300) { track->num_cb = 1; @@ -3427,6 +3449,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++) { diff --git a/drivers/gpu/drm/radeon/r100_track.h b/drivers/gpu/drm/radeon/r100_track.h index af65600..0584e26 100644 --- a/drivers/gpu/drm/radeon/r100_track.h +++ b/drivers/gpu/drm/radeon/r100_track.h @@ -73,11 +73,14 @@ 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 aa_dirty; + bool aaresolve; }; int r100_cs_track_check(struct radeon_device *rdev, struct r100_cs_track *track); diff --git a/drivers/gpu/drm/radeon/r300.c b/drivers/gpu/drm/radeon/r300.c index 19a7ef7..76db6e9 100644 --- a/drivers/gpu/drm/radeon/r300.c +++ b/drivers/gpu/drm/radeon/r300.c @@ -1056,6 +1056,27 @@ static int r300_packet0_check(struct radeon_cs_parser *p, /* RB3D_BLENDCNTL */ track->blend_read_enable = !!(idx_value & (1 << 2)); 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 0x4be8: /* valid register only on RV530 */ if (p->rdev->family == CHIP_RV530) diff --git a/drivers/gpu/drm/radeon/r300_reg.h b/drivers/gpu/drm/radeon/r300_reg.h index 1a0d536..f0bce39 100644 --- a/drivers/gpu/drm/radeon/r300_reg.h +++ b/drivers/gpu/drm/radeon/r300_reg.h @@ -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 */ diff --git a/drivers/gpu/drm/radeon/reg_srcs/r300 b/drivers/gpu/drm/radeon/reg_srcs/r300 index 1e97b2d..0aa4aa0 100644 --- a/drivers/gpu/drm/radeon/reg_srcs/r300 +++ b/drivers/gpu/drm/radeon/reg_srcs/r300 @@ -707,9 +707,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 diff --git a/drivers/gpu/drm/radeon/reg_srcs/r420 b/drivers/gpu/drm/radeon/reg_srcs/r420 index e958980..d2c4c22 100644 --- a/drivers/gpu/drm/radeon/reg_srcs/r420 +++ b/drivers/gpu/drm/radeon/reg_srcs/r420 @@ -773,9 +773,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 diff --git a/drivers/gpu/drm/radeon/reg_srcs/rs600 b/drivers/gpu/drm/radeon/reg_srcs/rs600 index 83e8bc0..b51dfc6 100644 --- a/drivers/gpu/drm/radeon/reg_srcs/rs600 +++ b/drivers/gpu/drm/radeon/reg_srcs/rs600 @@ -773,9 +773,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 diff --git a/drivers/gpu/drm/radeon/reg_srcs/rv515 b/drivers/gpu/drm/radeon/reg_srcs/rv515 index 1e46233..efae202 100644 --- a/drivers/gpu/drm/radeon/reg_srcs/rv515 +++ b/drivers/gpu/drm/radeon/reg_srcs/rv515 @@ -468,9 +468,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 -- 1.7.0.4 From ffde90f78dc928573f3f7e14150b7318871aca4e Mon Sep 17 00:00:00 2001 From: Dave Airlie <airlied@redhat.com> Date: Sun, 20 Feb 2011 21:57:32 +0000 Subject: [PATCH 2/2] drm/radeon: fix regression with AA resolve checking, CVE-2011-1016 BugLink: http://bugs.launchpad.net/bugs/745686 CVE-2011-1016 Some userspaces can emit a whole packet without disabling AA resolve by the looks of it, so we have to deal with them. Signed-off-by: Dave Airlie <airlied@redhat.com> Tested-by: Jorg Otte <jrg.otte@googlemail.com> (cherry picked from commit 45e4039c3aea597ede44a264cea322908cdedfe9) Signed-off-by: Tim Gardner <tim.gardner@canonical.com> --- drivers/gpu/drm/radeon/r100.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index 2a5c3ae..ba1ffd8 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c @@ -3449,7 +3449,7 @@ 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->aaresolve = false; track->aa.robj = NULL; }