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:
Michel Dänzer 2006-08-26 12:21:11 +02:00
parent ea57099973
commit b99e332236

View file

@ -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;
}