From 1fbfd9eb32220a10d66373b77172965cfeccd4f7 Mon Sep 17 00:00:00 2001 From: Thomas Hellstrom Date: Mon, 6 Dec 2004 11:19:23 +0000 Subject: Security and optimization fixes for the via drm: 1. The command verifier was never initialized in the non-core source tree. 2. Check added that the AGP ring buffer has been initialized before accepting command buffer. 3. Free space check in the AGP buffer is moved to after command verification, which is more optimal in most cases. --- shared-core/via_dma.c | 18 +++++++++++++----- shared-core/via_drv.h | 4 ++-- shared/via.h | 4 ++-- shared/via_dma.c | 19 ++++++++++++++----- shared/via_map.c | 1 + 5 files changed, 32 insertions(+), 14 deletions(-) diff --git a/shared-core/via_dma.c b/shared-core/via_dma.c index 0c2ac470..ac7b7bea 100644 --- a/shared-core/via_dma.c +++ b/shared-core/via_dma.c @@ -170,19 +170,22 @@ int via_dma_init(DRM_IOCTL_ARGS) static int via_dispatch_cmdbuffer(drm_device_t * dev, drm_via_cmdbuffer_t * cmd) { - drm_via_private_t *dev_priv = dev->dev_private; + drm_via_private_t *dev_priv; uint32_t *vb; int ret; + dev_priv = (drm_via_private_t *) dev->dev_private; + + if (dev_priv->ring.virtual_start == NULL) { + DRM_ERROR("%s called without initializing AGP ring buffer.\n", + __FUNCTION__); + return DRM_ERR(EFAULT); + } if (cmd->size > pci_bufsiz && pci_bufsiz > 0) { return DRM_ERR(ENOMEM); } - vb = via_check_dma(dev_priv, cmd->size); - if (vb == NULL) { - return DRM_ERR(EAGAIN); - } if (DRM_COPY_FROM_USER(pci_buf, cmd->buf, cmd->size)) return DRM_ERR(EFAULT); @@ -198,6 +201,11 @@ static int via_dispatch_cmdbuffer(drm_device_t * dev, drm_via_cmdbuffer_t * cmd) return ret; } + vb = via_check_dma(dev_priv, cmd->size); + if (vb == NULL) { + return DRM_ERR(EAGAIN); + } + memcpy(vb, pci_buf, cmd->size); dev_priv->dma_low += cmd->size; diff --git a/shared-core/via_drv.h b/shared-core/via_drv.h index 13a93b78..e905a606 100644 --- a/shared-core/via_drv.h +++ b/shared-core/via_drv.h @@ -28,11 +28,11 @@ #define DRIVER_NAME "via" #define DRIVER_DESC "VIA Unichrome" -#define DRIVER_DATE "20041204" +#define DRIVER_DATE "20041206" #define DRIVER_MAJOR 2 #define DRIVER_MINOR 2 -#define DRIVER_PATCHLEVEL 0 +#define DRIVER_PATCHLEVEL 1 typedef struct drm_via_ring_buffer { drm_map_t map; diff --git a/shared/via.h b/shared/via.h index 423efc6b..5a5091b6 100644 --- a/shared/via.h +++ b/shared/via.h @@ -30,11 +30,11 @@ #define DRIVER_NAME "via" #define DRIVER_DESC "VIA Unichrome" -#define DRIVER_DATE "20041204" +#define DRIVER_DATE "20041206" #define DRIVER_MAJOR 2 #define DRIVER_MINOR 2 -#define DRIVER_PATCHLEVEL 0 +#define DRIVER_PATCHLEVEL 1 #define DRIVER_IOCTLS \ [DRM_IOCTL_NR(DRM_IOCTL_VIA_ALLOCMEM)] = { via_mem_alloc, 1, 0 }, \ diff --git a/shared/via_dma.c b/shared/via_dma.c index fbd3f6cb..cfb1ac38 100644 --- a/shared/via_dma.c +++ b/shared/via_dma.c @@ -171,19 +171,23 @@ int via_dma_init(DRM_IOCTL_ARGS) static int via_dispatch_cmdbuffer(drm_device_t * dev, drm_via_cmdbuffer_t * cmd) { - drm_via_private_t *dev_priv = dev->dev_private; + drm_via_private_t *dev_priv; uint32_t *vb; int ret; + dev_priv = (drm_via_private_t *) dev->dev_private; + + if (dev_priv->ring.virtual_start == NULL) { + DRM_ERROR("%s called without initializing AGP ring buffer.\n", + __FUNCTION__); + return DRM_ERR(EFAULT); + } + if (cmd->size > pci_bufsiz && pci_bufsiz > 0) { return DRM_ERR(ENOMEM); } - vb = via_check_dma(dev_priv, cmd->size); - if (vb == NULL) { - return DRM_ERR(EAGAIN); - } if (DRM_COPY_FROM_USER(pci_buf, cmd->buf, cmd->size)) return DRM_ERR(EFAULT); @@ -199,6 +203,11 @@ static int via_dispatch_cmdbuffer(drm_device_t * dev, drm_via_cmdbuffer_t * cmd) return ret; } + vb = via_check_dma(dev_priv, cmd->size); + if (vb == NULL) { + return DRM_ERR(EAGAIN); + } + memcpy(vb, pci_buf, cmd->size); dev_priv->dma_low += cmd->size; diff --git a/shared/via_map.c b/shared/via_map.c index 3aa66a17..ac8f105f 100644 --- a/shared/via_map.c +++ b/shared/via_map.c @@ -33,6 +33,7 @@ int via_do_init_map(drm_device_t * dev, drm_via_init_t * init) DRM_DEBUG("%s\n", __FUNCTION__); + via_init_command_verifier(); dev_priv = DRM(alloc) (sizeof(drm_via_private_t), DRM_MEM_DRIVER); if (dev_priv == NULL) return -ENOMEM; -- cgit v1.2.3