mirror of
https://gitlab.freedesktop.org/mesa/drm.git
synced 2026-05-05 13:38:04 +02:00
Bug #7595: Avoid u32 overflows in radeon_check_and_fixup_offset().
The overflows could cause valid offsets to get rejected under some circumstances, e.g. when the framebuffer resides at the very end of the card's address space.
This commit is contained in:
parent
ea57099973
commit
b99e332236
1 changed files with 12 additions and 13 deletions
|
|
@ -42,7 +42,11 @@ static __inline__ int radeon_check_and_fixup_offset(drm_radeon_private_t *
|
|||
drm_file_t * filp_priv,
|
||||
u32 * offset)
|
||||
{
|
||||
u32 off = *offset;
|
||||
u64 off = *offset;
|
||||
u32 fb_start = dev_priv->fb_location;
|
||||
u32 fb_end = fb_start + dev_priv->fb_size - 1;
|
||||
u32 gart_start = dev_priv->gart_vm_start;
|
||||
u32 gart_end = gart_start + dev_priv->gart_size - 1;
|
||||
struct drm_radeon_driver_file_fields *radeon_priv;
|
||||
|
||||
/* Hrm ... the story of the offset ... So this function converts
|
||||
|
|
@ -62,10 +66,8 @@ static __inline__ int radeon_check_and_fixup_offset(drm_radeon_private_t *
|
|||
/* First, the best case, the offset already lands in either the
|
||||
* framebuffer or the GART mapped space
|
||||
*/
|
||||
if ((off >= dev_priv->fb_location &&
|
||||
off < (dev_priv->fb_location + dev_priv->fb_size)) ||
|
||||
(off >= dev_priv->gart_vm_start &&
|
||||
off < (dev_priv->gart_vm_start + dev_priv->gart_size)))
|
||||
if ((off >= fb_start && off <= fb_end) ||
|
||||
(off >= gart_start && off <= gart_end))
|
||||
return 0;
|
||||
|
||||
/* Ok, that didn't happen... now check if we have a zero based
|
||||
|
|
@ -78,16 +80,13 @@ static __inline__ int radeon_check_and_fixup_offset(drm_radeon_private_t *
|
|||
}
|
||||
|
||||
/* Finally, assume we aimed at a GART offset if beyond the fb */
|
||||
if (off > (dev_priv->fb_location + dev_priv->fb_size))
|
||||
off = off - (dev_priv->fb_location + dev_priv->fb_size) +
|
||||
dev_priv->gart_vm_start;
|
||||
if (off > fb_end)
|
||||
off = off - fb_end - 1 + gart_start;
|
||||
|
||||
/* Now recheck and fail if out of bounds */
|
||||
if ((off >= dev_priv->fb_location &&
|
||||
off < (dev_priv->fb_location + dev_priv->fb_size)) ||
|
||||
(off >= dev_priv->gart_vm_start &&
|
||||
off < (dev_priv->gart_vm_start + dev_priv->gart_size))) {
|
||||
DRM_DEBUG("offset fixed up to 0x%x\n", off);
|
||||
if ((off >= fb_start && off <= fb_end) ||
|
||||
(off >= gart_start && off <= gart_end)) {
|
||||
DRM_DEBUG("offset fixed up to 0x%x\n", (unsigned int)off);
|
||||
*offset = off;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue