[R300] securing r300 drm

2005-06-21 Thread Vladimir Dergachev


Now that the driver paints usable pictures without lockups on many cards,
including AGP versions of X800 and Mobility M10, it would make sense to 
ready it for inclusion into main DRI codebase.


I do not think that elusive lockups of Radeon 9800 cards, or issues with 
PowerPC will require any drastic changes.


As we discussed earlier, the major reason against inclusion into 
mainstream DRI CVS is that the driver is not secure in its current state.


Below, I will attempt to list current known issues - please reply with 
your additions.


  * r300_emit_unchecked_state - it is not as unchecked as it has been
initially, however a few poorly checked registers remain:

from r300_cmdbuf.c:

ADD_RANGE(R300_RB3D_COLOROFFSET0, 1); /* Dangerous */
ADD_RANGE(R300_RB3D_COLORPITCH0, 1); /* Dangerous */
/* .. snip ... */
ADD_RANGE(R300_RB3D_DEPTHOFFSET, 2); /* Dangerous */

In principle an attacker can set these to point to AGP or system
RAM and then cause a paint operation to overwrite particular
memory range.

Ideally we should check that these point inside the framebuffer,
i.e. are within range specified by MC_FB_LOCATION register.

/* Texture offset is dangerous and needs more checking */
ADD_RANGE(R300_TX_OFFSET_0, 16);

I don't think texture offsets are ever written to, however if they
point in the wrong place they can be used to read memory directly.

ideally we would check these to be either with MC_FB_LOCATION
or MC_AGP_LOCATION ranges. Problem is what do we do on PCI cards ?
use AIC controller settings ?

  * r300_emit_raw - we do not have code that checks any of bufferred 3d
packets, in particular VBUF_2, IMMD_2, INDX_2 and INDX_BUFFER.

I think that none of these can be exploited except to cause a lockup -
please correct me if I am wrong

  * r300_emit_raw - RADEON_3D_LOAD_VBPNTR - this sets offsets and so
like texture offset registers could be exploited to read protected
memory locations.

Again, we need to check the offsets against something reasonable.

  * anything I forgot ?

best

   Vladimir Dergachev


---
SF.Net email is sponsored by: Discover Easy Linux Migration Strategies
from IBM. Find simple to follow Roadmaps, straightforward articles,
informative Webcasts and more! Get everything you need to get up to
speed, fast. http://ads.osdn.com/?ad_id=7477alloc_id=16492op=click
--
___
Dri-devel mailing list
Dri-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/dri-devel


Re: [R300] securing r300 drm

2005-06-21 Thread Eric Anholt
On Tue, 2005-06-21 at 14:57 -0400, Vladimir Dergachev wrote:
   /* Texture offset is dangerous and needs more checking */
   ADD_RANGE(R300_TX_OFFSET_0, 16);
 
  I don't think texture offsets are ever written to, however if they
  point in the wrong place they can be used to read memory directly.
 
  ideally we would check these to be either with MC_FB_LOCATION
  or MC_AGP_LOCATION ranges. Problem is what do we do on PCI cards ?
  use AIC controller settings ?

Just verify that the location is within expected areas of the card's
virtual address space, like you do for color/depth offsets, right?

-- 
Eric Anholt [EMAIL PROTECTED]
http://people.freebsd.org/~anholt/  [EMAIL PROTECTED]


---
SF.Net email is sponsored by: Discover Easy Linux Migration Strategies
from IBM. Find simple to follow Roadmaps, straightforward articles,
informative Webcasts and more! Get everything you need to get up to
speed, fast. http://ads.osdn.com/?ad_id=7477alloc_id=16492op=click
--
___
Dri-devel mailing list
Dri-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/dri-devel


Re: [R300] securing r300 drm

2005-06-21 Thread Vladimir Dergachev



On Tue, 21 Jun 2005, Eric Anholt wrote:


On Tue, 2005-06-21 at 14:57 -0400, Vladimir Dergachev wrote:

/* Texture offset is dangerous and needs more checking */
ADD_RANGE(R300_TX_OFFSET_0, 16);

 I don't think texture offsets are ever written to, however if they
 point in the wrong place they can be used to read memory directly.

 ideally we would check these to be either with MC_FB_LOCATION
 or MC_AGP_LOCATION ranges. Problem is what do we do on PCI cards ?
 use AIC controller settings ?


Just verify that the location is within expected areas of the card's
virtual address space, like you do for color/depth offsets, right?


Yes, the question is what these are for PCI cards. I guess AIC should have 
a register similar to MC_AGP_LOCATION.


best

Vladimir Dergachev



--
Eric Anholt [EMAIL PROTECTED]
http://people.freebsd.org/~anholt/  [EMAIL PROTECTED]




---
SF.Net email is sponsored by: Discover Easy Linux Migration Strategies
from IBM. Find simple to follow Roadmaps, straightforward articles,
informative Webcasts and more! Get everything you need to get up to
speed, fast. http://ads.osdn.com/?ad_id=7477alloc_id=16492op=click
--
___
Dri-devel mailing list
Dri-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/dri-devel


Re: [R300] securing r300 drm

2005-06-21 Thread Eric Anholt
On Tue, 2005-06-21 at 16:56 -0400, Vladimir Dergachev wrote:
 
 On Tue, 21 Jun 2005, Eric Anholt wrote:
 
  On Tue, 2005-06-21 at 14:57 -0400, Vladimir Dergachev wrote:
 /* Texture offset is dangerous and needs more checking */
 ADD_RANGE(R300_TX_OFFSET_0, 16);
 
   I don't think texture offsets are ever written to, however if they
   point in the wrong place they can be used to read memory directly.
 
   ideally we would check these to be either with MC_FB_LOCATION
   or MC_AGP_LOCATION ranges. Problem is what do we do on PCI cards ?
   use AIC controller settings ?
 
  Just verify that the location is within expected areas of the card's
  virtual address space, like you do for color/depth offsets, right?
 
 Yes, the question is what these are for PCI cards. I guess AIC should have 
 a register similar to MC_AGP_LOCATION.

It looks like you use the same structure entries on both.  The check for
is not in bad system memory is:
if (off = dev_priv-fb_location 
off  (dev_priv-gart_vm_start + dev_priv-gart_size))
return 0;

This is assuming that you've got the layout the same as on old radeon
DRM, with the gart immediately following the fb aperture.

-- 
Eric Anholt [EMAIL PROTECTED]
http://people.freebsd.org/~anholt/  [EMAIL PROTECTED]


---
SF.Net email is sponsored by: Discover Easy Linux Migration Strategies
from IBM. Find simple to follow Roadmaps, straightforward articles,
informative Webcasts and more! Get everything you need to get up to
speed, fast. http://ads.osdn.com/?ad_id=7477alloc_id=16492op=click
--
___
Dri-devel mailing list
Dri-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/dri-devel


Re: [R300] securing r300 drm

2005-06-21 Thread Nicolai Haehnle
On Tuesday 21 June 2005 20:57, Vladimir Dergachev wrote:
 Now that the driver paints usable pictures without lockups on many cards,
 including AGP versions of X800 and Mobility M10, it would make sense to 
 ready it for inclusion into main DRI codebase.
 
 I do not think that elusive lockups of Radeon 9800 cards, or issues with 
 PowerPC will require any drastic changes.
 
 As we discussed earlier, the major reason against inclusion into 
 mainstream DRI CVS is that the driver is not secure in its current state.
 
 Below, I will attempt to list current known issues - please reply with 
 your additions.
 
* r300_emit_unchecked_state - it is not as unchecked as it has been
  initially, however a few poorly checked registers remain:

Those poorly checked registers should be moved out of unchecked_state and 
into its own function. Adding these checks into unchecked_state will just 
add overhead to what should be a fast path.

The idea would be to add something like r300_emit_special_state which 
doesn't use register addresses but has subcommands like the state setting 
for radeon/r200.

  from r300_cmdbuf.c:
 
   ADD_RANGE(R300_RB3D_COLOROFFSET0, 1); /* Dangerous */
   ADD_RANGE(R300_RB3D_COLORPITCH0, 1); /* Dangerous */
/* .. snip ... */
   ADD_RANGE(R300_RB3D_DEPTHOFFSET, 2); /* Dangerous */
 
  In principle an attacker can set these to point to AGP or system
  RAM and then cause a paint operation to overwrite particular
  memory range.
 
  Ideally we should check that these point inside the framebuffer,
  i.e. are within range specified by MC_FB_LOCATION register.

Right. Actually, to be on the safe side, we'd have to set min/max clipping 
rects at the same time as setting those buffer offsets. This is currently 
not a problem, but it will become one when (if? ;)) we implement 
framebuffer_object etc.

/* Texture offset is dangerous and needs more checking */
   ADD_RANGE(R300_TX_OFFSET_0, 16);
 
  I don't think texture offsets are ever written to, however if 
they
  point in the wrong place they can be used to read memory 
directly.

Setting those texture offsets wrong can actually lock up the machine as I 
found out when I temporarily put MC_FB_LOCATION into its natural position 
(i.e. where it's put on older radeons).

  ideally we would check these to be either with MC_FB_LOCATION
  or MC_AGP_LOCATION ranges. Problem is what do we do on PCI 
cards ?
  use AIC controller settings ?

Unfortunately, I don't know enough about PCI to comment, and what's AIC 
anyway? I've seen some register names with AIC in it, but they don't really 
seem to be used.

* r300_emit_raw - we do not have code that checks any of bufferred 3d
  packets, in particular VBUF_2, IMMD_2, INDX_2 and INDX_BUFFER.
 
  I think that none of these can be exploited except to cause a lockup 
-
  please correct me if I am wrong

* r300_emit_raw - RADEON_3D_LOAD_VBPNTR - this sets offsets and so
  like texture offset registers could be exploited to read protected
  memory locations.
 
  Again, we need to check the offsets against something reasonable.

Note that by putting the offset at the end of allowed memory and setting the 
number of vertices very high, you could read memory that you shouldn't have 
access to.

But the more important thing is: What's up with r300_emit_raw anyway? It was 
originally supposed to do what the name suggests: Emit raw data into the 
ring buffer, purely as a hack for experimentation.

People have bent it in extreme ways, so it has clearly gone beyond that, and 
that's a Bad Thing. For one thing, r300_emit_raw doesn't get cliprects 
right. If you have more than four cliprects, you need to emit rendering 
commands multiple times.

Seriously, all the stuff that uses emit_raw should just be migrated to use 
r300_emit_packet3, which will clean this up a lot.

 
* anything I forgot ?

Talking about security, have a look at radeon_state.c. Where on earth does 
*this* come from:

/* Allocate an in-kernel area and copy in the cmdbuf.  Do this to 
avoid
 * races between checking values and using those values in other 
code,
 * and simply to avoid a lot of function calls to copy in data.
 */
orig_bufsz = cmdbuf.bufsz;
if (orig_bufsz != 0) {
kbuf = drm_alloc(cmdbuf.bufsz, DRM_MEM_DRIVER);
if (kbuf == NULL)
return DRM_ERR(ENOMEM);
if (DRM_COPY_FROM_USER(kbuf, cmdbuf.buf, cmdbuf.bufsz)) {
drm_free(kbuf, orig_bufsz, DRM_MEM_DRIVER);
return DRM_ERR(EFAULT);
}
cmdbuf.buf = kbuf;
}

This just shouts insanity. It calls kmalloc every single time you emit a 
command buffer!

The security issue mentioned in the comment is real, but there's a really 
simple rule of thumb that eliminates it