On Sat, Nov 08, 2014 at 11:51:30PM +0100, Glenn Kennard wrote:
> Signed-off-by: Glenn Kennard <glenn.kennard at gmail.com>

NAK insecure. This is missing any kind of boundary checking for the
indirect buffer and thus can be abuse.

> ---
> See patch sent to mesa-dev at lists.freedesktop.org for userspace usage.
> 
>  drivers/gpu/drm/radeon/evergreen_cs.c | 76 
> +++++++++++++++++++++++++++++++++++
>  drivers/gpu/drm/radeon/evergreend.h   |  1 +
>  drivers/gpu/drm/radeon/radeon_drv.c   |  3 +-
>  3 files changed, 79 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c 
> b/drivers/gpu/drm/radeon/evergreen_cs.c
> index 5c8b358..6173df3 100644
> --- a/drivers/gpu/drm/radeon/evergreen_cs.c
> +++ b/drivers/gpu/drm/radeon/evergreen_cs.c
> @@ -1896,6 +1896,19 @@ static int evergreen_packet3_check(struct 
> radeon_cs_parser *p,
>               }
>               break;
>       }
> +     case PACKET3_INDEX_BUFFER_SIZE:
> +     {
> +             if (pkt->count != 0) {
> +                     DRM_ERROR("bad INDEX_BUFFER_SIZE\n");
> +                     return -EINVAL;
> +             }
> +             r = evergreen_cs_track_check(p);
> +             if (r) {
> +                     dev_warn(p->dev, "%s:%d invalid cmd stream\n", 
> __func__, __LINE__);
> +                     return r;
> +             }
> +             break;
> +     }
>       case PACKET3_DRAW_INDEX:
>       {
>               uint64_t offset;
> @@ -2006,6 +2019,68 @@ static int evergreen_packet3_check(struct 
> radeon_cs_parser *p,
>                       return r;
>               }
>               break;
> +     case PACKET3_SET_BASE:
> +     {
> +             /*
> +             DW 1 HEADER Header of the packet. Shader_Type in bit 1 of the 
> Header will correspond to the shader type of the Load, see Type-3 Packet.
> +                2 BASE_INDEX Bits [3:0] BASE_INDEX - Base Index specifies 
> which base address is specified in the last two DWs.
> +                  0001: DX11 Draw_Index_Indirect Patch Table Base: Base 
> address for Draw_Index_Indirect data.
> +                3 ADDRESS_LO Bits [31:3] - Lower bits of QWORD-Aligned 
> Address. Bits [2:0] - Reserved
> +                4 ADDRESS_HI Bits [31:8] - Reserved. Bits [7:0] - Upper bits 
> of Address [47:32]
> +             */
> +             uint64_t offset;
> +
> +             if (pkt->count != 2) {
> +                     DRM_ERROR("bad SET_BASE\n");
> +                     return -EINVAL;
> +             }
> +
> +             /* currently only supporting setting indirect draw buffer base 
> address */
> +             if (radeon_get_ib_value(p, idx) != 1) {
> +                     DRM_ERROR("bad SET_BASE\n");
> +                     return -EINVAL;
> +             }
> +
> +             r = radeon_cs_packet_next_reloc(p, &reloc, 0);
> +             if (r) {
> +                     DRM_ERROR("bad SET_BASE\n");
> +                     return -EINVAL;
> +             }
> +
> +             offset = reloc->gpu_offset +
> +                      radeon_get_ib_value(p, idx+1) +
> +                      ((u64)(radeon_get_ib_value(p, idx+2) & 0xff) << 32);
> +
> +             ib[idx+1] = offset;
> +             ib[idx+2] = upper_32_bits(offset) & 0xff;
> +
> +             r = evergreen_cs_track_check(p);
> +             if (r) {
> +                     dev_warn(p->dev, "%s:%d invalid cmd stream\n", 
> __func__, __LINE__);
> +                     return r;
> +             }
> +             break;
> +     }
> +     case PACKET3_DRAW_INDIRECT:
> +     case PACKET3_DRAW_INDEX_INDIRECT:
> +     case PACKET3_DRAW_INDIRECT_MULTI:
> +     {
> +             /*
> +             DW 1 HEADER
> +                2 DATA_OFFSET Bits [31:0] + byte aligned offset where the 
> required data structure starts. Bits 1:0 are zero
> +                3 DRAW_INITIATOR Draw Initiator Register. Written to the 
> VGT_DRAW_INITIATOR register for the assigned context
> +             */
> +             if (pkt->count != 1) {
> +                     DRM_ERROR("bad DRAW_INDIRECT\n");
> +                     return -EINVAL;
> +             }
> +             r = evergreen_cs_track_check(p);
> +             if (r) {
> +                     dev_warn(p->dev, "%s:%d invalid cmd stream\n", 
> __func__, __LINE__);
> +                     return r;
> +             }
> +             break;
> +     }
>       case PACKET3_DISPATCH_DIRECT:
>               if (pkt->count != 3) {
>                       DRM_ERROR("bad DISPATCH_DIRECT\n");
> @@ -3260,6 +3335,7 @@ static int evergreen_vm_packet3_check(struct 
> radeon_device *rdev,
>       case PACKET3_DRAW_INDEX_OFFSET:
>       case PACKET3_INDEX_TYPE:
>       case PACKET3_DRAW_INDEX:
> +     case PACKET3_DRAW_INDIRECT_MULTI:
>       case PACKET3_DRAW_INDEX_AUTO:
>       case PACKET3_DRAW_INDEX_IMMD:
>       case PACKET3_NUM_INSTANCES:
> diff --git a/drivers/gpu/drm/radeon/evergreend.h 
> b/drivers/gpu/drm/radeon/evergreend.h
> index b066d67..5d4c5f2 100644
> --- a/drivers/gpu/drm/radeon/evergreend.h
> +++ b/drivers/gpu/drm/radeon/evergreend.h
> @@ -1553,6 +1553,7 @@
>  #define      PACKET3_DRAW_INDEX_OFFSET                       0x29
>  #define      PACKET3_INDEX_TYPE                              0x2A
>  #define      PACKET3_DRAW_INDEX                              0x2B
> +#define PACKET3_DRAW_INDIRECT_MULTI                  0x2C
>  #define      PACKET3_DRAW_INDEX_AUTO                         0x2D
>  #define      PACKET3_DRAW_INDEX_IMMD                         0x2E
>  #define      PACKET3_NUM_INSTANCES                           0x2F
> diff --git a/drivers/gpu/drm/radeon/radeon_drv.c 
> b/drivers/gpu/drm/radeon/radeon_drv.c
> index dcffa30..fbd1f73 100644
> --- a/drivers/gpu/drm/radeon/radeon_drv.c
> +++ b/drivers/gpu/drm/radeon/radeon_drv.c
> @@ -86,9 +86,10 @@
>   *   2.39.0 - Add INFO query for number of active CUs
>   *   2.40.0 - Add RADEON_GEM_GTT_WC/UC, flush HDP cache before submitting
>   *            CS to GPU on >= r600
> + *   2.41.0 - evergreen/cayman: Add SET_BASE/DRAW_INDIRECT command parsing 
> support
>   */
>  #define KMS_DRIVER_MAJOR     2
> -#define KMS_DRIVER_MINOR     40
> +#define KMS_DRIVER_MINOR     41
>  #define KMS_DRIVER_PATCHLEVEL        0
>  int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags);
>  int radeon_driver_unload_kms(struct drm_device *dev);
> -- 
> 1.9.1
> 
> _______________________________________________
> dri-devel mailing list
> dri-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/dri-devel

Reply via email to