aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/evergreen_cs.c
diff options
context:
space:
mode:
authorJerome Glisse <jglisse@redhat.com>2013-02-11 08:57:18 -0500
committerDave Airlie <airlied@redhat.com>2013-02-12 01:56:25 -0500
commitde0babd60d8d43b58fd06a7803151d32cb589af0 (patch)
tree4791ef696001b44741deb85c092c1cc43654ab6b /drivers/gpu/drm/radeon/evergreen_cs.c
parente28f639eeaa97b6029b0db8890b2a4ce99e642c6 (diff)
drm/radeon: enforce use of radeon_get_ib_value when reading user cmd
When ever parsing cmd buffer supplied by userspace we need to use radeon_get_ib_value rather than directly accessing the ib as the user cmd might not yet be copied into the ib thus the parser might read value that does not correspond to what user is sending and possibly allowing user to send malicious command undected. Signed-off-by: Jerome Glisse <jglisse@redhat.com> Reviewed-by: Alex Deucher <alexander.deucher@amd.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/radeon/evergreen_cs.c')
-rw-r--r--drivers/gpu/drm/radeon/evergreen_cs.c86
1 files changed, 43 insertions, 43 deletions
diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c
index 7a445666e71f..ee4cff534f10 100644
--- a/drivers/gpu/drm/radeon/evergreen_cs.c
+++ b/drivers/gpu/drm/radeon/evergreen_cs.c
@@ -2909,14 +2909,14 @@ int evergreen_dma_cs_parse(struct radeon_cs_parser *p)
2909 return -EINVAL; 2909 return -EINVAL;
2910 } 2910 }
2911 if (tiled) { 2911 if (tiled) {
2912 dst_offset = ib[idx+1]; 2912 dst_offset = radeon_get_ib_value(p, idx+1);
2913 dst_offset <<= 8; 2913 dst_offset <<= 8;
2914 2914
2915 ib[idx+1] += (u32)(dst_reloc->lobj.gpu_offset >> 8); 2915 ib[idx+1] += (u32)(dst_reloc->lobj.gpu_offset >> 8);
2916 p->idx += count + 7; 2916 p->idx += count + 7;
2917 } else { 2917 } else {
2918 dst_offset = ib[idx+1]; 2918 dst_offset = radeon_get_ib_value(p, idx+1);
2919 dst_offset |= ((u64)(ib[idx+2] & 0xff)) << 32; 2919 dst_offset |= ((u64)(radeon_get_ib_value(p, idx+2) & 0xff)) << 32;
2920 2920
2921 ib[idx+1] += (u32)(dst_reloc->lobj.gpu_offset & 0xfffffffc); 2921 ib[idx+1] += (u32)(dst_reloc->lobj.gpu_offset & 0xfffffffc);
2922 ib[idx+2] += upper_32_bits(dst_reloc->lobj.gpu_offset) & 0xff; 2922 ib[idx+2] += upper_32_bits(dst_reloc->lobj.gpu_offset) & 0xff;
@@ -2954,12 +2954,12 @@ int evergreen_dma_cs_parse(struct radeon_cs_parser *p)
2954 DRM_ERROR("bad L2T, frame to fields DMA_PACKET_COPY\n"); 2954 DRM_ERROR("bad L2T, frame to fields DMA_PACKET_COPY\n");
2955 return -EINVAL; 2955 return -EINVAL;
2956 } 2956 }
2957 dst_offset = ib[idx+1]; 2957 dst_offset = radeon_get_ib_value(p, idx+1);
2958 dst_offset <<= 8; 2958 dst_offset <<= 8;
2959 dst2_offset = ib[idx+2]; 2959 dst2_offset = radeon_get_ib_value(p, idx+2);
2960 dst2_offset <<= 8; 2960 dst2_offset <<= 8;
2961 src_offset = ib[idx+8]; 2961 src_offset = radeon_get_ib_value(p, idx+8);
2962 src_offset |= ((u64)(ib[idx+9] & 0xff)) << 32; 2962 src_offset |= ((u64)(radeon_get_ib_value(p, idx+9) & 0xff)) << 32;
2963 if ((src_offset + (count * 4)) > radeon_bo_size(src_reloc->robj)) { 2963 if ((src_offset + (count * 4)) > radeon_bo_size(src_reloc->robj)) {
2964 dev_warn(p->dev, "DMA L2T, frame to fields src buffer too small (%llu %lu)\n", 2964 dev_warn(p->dev, "DMA L2T, frame to fields src buffer too small (%llu %lu)\n",
2965 src_offset + (count * 4), radeon_bo_size(src_reloc->robj)); 2965 src_offset + (count * 4), radeon_bo_size(src_reloc->robj));
@@ -3014,12 +3014,12 @@ int evergreen_dma_cs_parse(struct radeon_cs_parser *p)
3014 DRM_ERROR("bad L2T, broadcast DMA_PACKET_COPY\n"); 3014 DRM_ERROR("bad L2T, broadcast DMA_PACKET_COPY\n");
3015 return -EINVAL; 3015 return -EINVAL;
3016 } 3016 }
3017 dst_offset = ib[idx+1]; 3017 dst_offset = radeon_get_ib_value(p, idx+1);
3018 dst_offset <<= 8; 3018 dst_offset <<= 8;
3019 dst2_offset = ib[idx+2]; 3019 dst2_offset = radeon_get_ib_value(p, idx+2);
3020 dst2_offset <<= 8; 3020 dst2_offset <<= 8;
3021 src_offset = ib[idx+8]; 3021 src_offset = radeon_get_ib_value(p, idx+8);
3022 src_offset |= ((u64)(ib[idx+9] & 0xff)) << 32; 3022 src_offset |= ((u64)(radeon_get_ib_value(p, idx+9) & 0xff)) << 32;
3023 if ((src_offset + (count * 4)) > radeon_bo_size(src_reloc->robj)) { 3023 if ((src_offset + (count * 4)) > radeon_bo_size(src_reloc->robj)) {
3024 dev_warn(p->dev, "DMA L2T, broadcast src buffer too small (%llu %lu)\n", 3024 dev_warn(p->dev, "DMA L2T, broadcast src buffer too small (%llu %lu)\n",
3025 src_offset + (count * 4), radeon_bo_size(src_reloc->robj)); 3025 src_offset + (count * 4), radeon_bo_size(src_reloc->robj));
@@ -3046,22 +3046,22 @@ int evergreen_dma_cs_parse(struct radeon_cs_parser *p)
3046 /* detile bit */ 3046 /* detile bit */
3047 if (idx_value & (1 << 31)) { 3047 if (idx_value & (1 << 31)) {
3048 /* tiled src, linear dst */ 3048 /* tiled src, linear dst */
3049 src_offset = ib[idx+1]; 3049 src_offset = radeon_get_ib_value(p, idx+1);
3050 src_offset <<= 8; 3050 src_offset <<= 8;
3051 ib[idx+1] += (u32)(src_reloc->lobj.gpu_offset >> 8); 3051 ib[idx+1] += (u32)(src_reloc->lobj.gpu_offset >> 8);
3052 3052
3053 dst_offset = ib[idx+7]; 3053 dst_offset = radeon_get_ib_value(p, idx+7);
3054 dst_offset |= ((u64)(ib[idx+8] & 0xff)) << 32; 3054 dst_offset |= ((u64)(radeon_get_ib_value(p, idx+8) & 0xff)) << 32;
3055 ib[idx+7] += (u32)(dst_reloc->lobj.gpu_offset & 0xfffffffc); 3055 ib[idx+7] += (u32)(dst_reloc->lobj.gpu_offset & 0xfffffffc);
3056 ib[idx+8] += upper_32_bits(dst_reloc->lobj.gpu_offset) & 0xff; 3056 ib[idx+8] += upper_32_bits(dst_reloc->lobj.gpu_offset) & 0xff;
3057 } else { 3057 } else {
3058 /* linear src, tiled dst */ 3058 /* linear src, tiled dst */
3059 src_offset = ib[idx+7]; 3059 src_offset = radeon_get_ib_value(p, idx+7);
3060 src_offset |= ((u64)(ib[idx+8] & 0xff)) << 32; 3060 src_offset |= ((u64)(radeon_get_ib_value(p, idx+8) & 0xff)) << 32;
3061 ib[idx+7] += (u32)(src_reloc->lobj.gpu_offset & 0xfffffffc); 3061 ib[idx+7] += (u32)(src_reloc->lobj.gpu_offset & 0xfffffffc);
3062 ib[idx+8] += upper_32_bits(src_reloc->lobj.gpu_offset) & 0xff; 3062 ib[idx+8] += upper_32_bits(src_reloc->lobj.gpu_offset) & 0xff;
3063 3063
3064 dst_offset = ib[idx+1]; 3064 dst_offset = radeon_get_ib_value(p, idx+1);
3065 dst_offset <<= 8; 3065 dst_offset <<= 8;
3066 ib[idx+1] += (u32)(dst_reloc->lobj.gpu_offset >> 8); 3066 ib[idx+1] += (u32)(dst_reloc->lobj.gpu_offset >> 8);
3067 } 3067 }
@@ -3098,12 +3098,12 @@ int evergreen_dma_cs_parse(struct radeon_cs_parser *p)
3098 DRM_ERROR("bad L2T, broadcast DMA_PACKET_COPY\n"); 3098 DRM_ERROR("bad L2T, broadcast DMA_PACKET_COPY\n");
3099 return -EINVAL; 3099 return -EINVAL;
3100 } 3100 }
3101 dst_offset = ib[idx+1]; 3101 dst_offset = radeon_get_ib_value(p, idx+1);
3102 dst_offset <<= 8; 3102 dst_offset <<= 8;
3103 dst2_offset = ib[idx+2]; 3103 dst2_offset = radeon_get_ib_value(p, idx+2);
3104 dst2_offset <<= 8; 3104 dst2_offset <<= 8;
3105 src_offset = ib[idx+8]; 3105 src_offset = radeon_get_ib_value(p, idx+8);
3106 src_offset |= ((u64)(ib[idx+9] & 0xff)) << 32; 3106 src_offset |= ((u64)(radeon_get_ib_value(p, idx+9) & 0xff)) << 32;
3107 if ((src_offset + (count * 4)) > radeon_bo_size(src_reloc->robj)) { 3107 if ((src_offset + (count * 4)) > radeon_bo_size(src_reloc->robj)) {
3108 dev_warn(p->dev, "DMA L2T, broadcast src buffer too small (%llu %lu)\n", 3108 dev_warn(p->dev, "DMA L2T, broadcast src buffer too small (%llu %lu)\n",
3109 src_offset + (count * 4), radeon_bo_size(src_reloc->robj)); 3109 src_offset + (count * 4), radeon_bo_size(src_reloc->robj));
@@ -3135,22 +3135,22 @@ int evergreen_dma_cs_parse(struct radeon_cs_parser *p)
3135 /* detile bit */ 3135 /* detile bit */
3136 if (idx_value & (1 << 31)) { 3136 if (idx_value & (1 << 31)) {
3137 /* tiled src, linear dst */ 3137 /* tiled src, linear dst */
3138 src_offset = ib[idx+1]; 3138 src_offset = radeon_get_ib_value(p, idx+1);
3139 src_offset <<= 8; 3139 src_offset <<= 8;
3140 ib[idx+1] += (u32)(src_reloc->lobj.gpu_offset >> 8); 3140 ib[idx+1] += (u32)(src_reloc->lobj.gpu_offset >> 8);
3141 3141
3142 dst_offset = ib[idx+7]; 3142 dst_offset = radeon_get_ib_value(p, idx+7);
3143 dst_offset |= ((u64)(ib[idx+8] & 0xff)) << 32; 3143 dst_offset |= ((u64)(radeon_get_ib_value(p, idx+8) & 0xff)) << 32;
3144 ib[idx+7] += (u32)(dst_reloc->lobj.gpu_offset & 0xfffffffc); 3144 ib[idx+7] += (u32)(dst_reloc->lobj.gpu_offset & 0xfffffffc);
3145 ib[idx+8] += upper_32_bits(dst_reloc->lobj.gpu_offset) & 0xff; 3145 ib[idx+8] += upper_32_bits(dst_reloc->lobj.gpu_offset) & 0xff;
3146 } else { 3146 } else {
3147 /* linear src, tiled dst */ 3147 /* linear src, tiled dst */
3148 src_offset = ib[idx+7]; 3148 src_offset = radeon_get_ib_value(p, idx+7);
3149 src_offset |= ((u64)(ib[idx+8] & 0xff)) << 32; 3149 src_offset |= ((u64)(radeon_get_ib_value(p, idx+8) & 0xff)) << 32;
3150 ib[idx+7] += (u32)(src_reloc->lobj.gpu_offset & 0xfffffffc); 3150 ib[idx+7] += (u32)(src_reloc->lobj.gpu_offset & 0xfffffffc);
3151 ib[idx+8] += upper_32_bits(src_reloc->lobj.gpu_offset) & 0xff; 3151 ib[idx+8] += upper_32_bits(src_reloc->lobj.gpu_offset) & 0xff;
3152 3152
3153 dst_offset = ib[idx+1]; 3153 dst_offset = radeon_get_ib_value(p, idx+1);
3154 dst_offset <<= 8; 3154 dst_offset <<= 8;
3155 ib[idx+1] += (u32)(dst_reloc->lobj.gpu_offset >> 8); 3155 ib[idx+1] += (u32)(dst_reloc->lobj.gpu_offset >> 8);
3156 } 3156 }
@@ -3176,10 +3176,10 @@ int evergreen_dma_cs_parse(struct radeon_cs_parser *p)
3176 switch (misc) { 3176 switch (misc) {
3177 case 0: 3177 case 0:
3178 /* L2L, byte */ 3178 /* L2L, byte */
3179 src_offset = ib[idx+2]; 3179 src_offset = radeon_get_ib_value(p, idx+2);
3180 src_offset |= ((u64)(ib[idx+4] & 0xff)) << 32; 3180 src_offset |= ((u64)(radeon_get_ib_value(p, idx+4) & 0xff)) << 32;
3181 dst_offset = ib[idx+1]; 3181 dst_offset = radeon_get_ib_value(p, idx+1);
3182 dst_offset |= ((u64)(ib[idx+3] & 0xff)) << 32; 3182 dst_offset |= ((u64)(radeon_get_ib_value(p, idx+3) & 0xff)) << 32;
3183 if ((src_offset + count) > radeon_bo_size(src_reloc->robj)) { 3183 if ((src_offset + count) > radeon_bo_size(src_reloc->robj)) {
3184 dev_warn(p->dev, "DMA L2L, byte src buffer too small (%llu %lu)\n", 3184 dev_warn(p->dev, "DMA L2L, byte src buffer too small (%llu %lu)\n",
3185 src_offset + count, radeon_bo_size(src_reloc->robj)); 3185 src_offset + count, radeon_bo_size(src_reloc->robj));
@@ -3216,12 +3216,12 @@ int evergreen_dma_cs_parse(struct radeon_cs_parser *p)
3216 DRM_ERROR("bad L2L, dw, broadcast DMA_PACKET_COPY\n"); 3216 DRM_ERROR("bad L2L, dw, broadcast DMA_PACKET_COPY\n");
3217 return -EINVAL; 3217 return -EINVAL;
3218 } 3218 }
3219 dst_offset = ib[idx+1]; 3219 dst_offset = radeon_get_ib_value(p, idx+1);
3220 dst_offset |= ((u64)(ib[idx+4] & 0xff)) << 32; 3220 dst_offset |= ((u64)(radeon_get_ib_value(p, idx+4) & 0xff)) << 32;
3221 dst2_offset = ib[idx+2]; 3221 dst2_offset = radeon_get_ib_value(p, idx+2);
3222 dst2_offset |= ((u64)(ib[idx+5] & 0xff)) << 32; 3222 dst2_offset |= ((u64)(radeon_get_ib_value(p, idx+5) & 0xff)) << 32;
3223 src_offset = ib[idx+3]; 3223 src_offset = radeon_get_ib_value(p, idx+3);
3224 src_offset |= ((u64)(ib[idx+6] & 0xff)) << 32; 3224 src_offset |= ((u64)(radeon_get_ib_value(p, idx+6) & 0xff)) << 32;
3225 if ((src_offset + (count * 4)) > radeon_bo_size(src_reloc->robj)) { 3225 if ((src_offset + (count * 4)) > radeon_bo_size(src_reloc->robj)) {
3226 dev_warn(p->dev, "DMA L2L, dw, broadcast src buffer too small (%llu %lu)\n", 3226 dev_warn(p->dev, "DMA L2L, dw, broadcast src buffer too small (%llu %lu)\n",
3227 src_offset + (count * 4), radeon_bo_size(src_reloc->robj)); 3227 src_offset + (count * 4), radeon_bo_size(src_reloc->robj));
@@ -3251,10 +3251,10 @@ int evergreen_dma_cs_parse(struct radeon_cs_parser *p)
3251 } 3251 }
3252 } else { 3252 } else {
3253 /* L2L, dw */ 3253 /* L2L, dw */
3254 src_offset = ib[idx+2]; 3254 src_offset = radeon_get_ib_value(p, idx+2);
3255 src_offset |= ((u64)(ib[idx+4] & 0xff)) << 32; 3255 src_offset |= ((u64)(radeon_get_ib_value(p, idx+4) & 0xff)) << 32;
3256 dst_offset = ib[idx+1]; 3256 dst_offset = radeon_get_ib_value(p, idx+1);
3257 dst_offset |= ((u64)(ib[idx+3] & 0xff)) << 32; 3257 dst_offset |= ((u64)(radeon_get_ib_value(p, idx+3) & 0xff)) << 32;
3258 if ((src_offset + (count * 4)) > radeon_bo_size(src_reloc->robj)) { 3258 if ((src_offset + (count * 4)) > radeon_bo_size(src_reloc->robj)) {
3259 dev_warn(p->dev, "DMA L2L, dw src buffer too small (%llu %lu)\n", 3259 dev_warn(p->dev, "DMA L2L, dw src buffer too small (%llu %lu)\n",
3260 src_offset + (count * 4), radeon_bo_size(src_reloc->robj)); 3260 src_offset + (count * 4), radeon_bo_size(src_reloc->robj));
@@ -3279,8 +3279,8 @@ int evergreen_dma_cs_parse(struct radeon_cs_parser *p)
3279 DRM_ERROR("bad DMA_PACKET_CONSTANT_FILL\n"); 3279 DRM_ERROR("bad DMA_PACKET_CONSTANT_FILL\n");
3280 return -EINVAL; 3280 return -EINVAL;
3281 } 3281 }
3282 dst_offset = ib[idx+1]; 3282 dst_offset = radeon_get_ib_value(p, idx+1);
3283 dst_offset |= ((u64)(ib[idx+3] & 0x00ff0000)) << 16; 3283 dst_offset |= ((u64)(radeon_get_ib_value(p, idx+3) & 0x00ff0000)) << 16;
3284 if ((dst_offset + (count * 4)) > radeon_bo_size(dst_reloc->robj)) { 3284 if ((dst_offset + (count * 4)) > radeon_bo_size(dst_reloc->robj)) {
3285 dev_warn(p->dev, "DMA constant fill buffer too small (%llu %lu)\n", 3285 dev_warn(p->dev, "DMA constant fill buffer too small (%llu %lu)\n",
3286 dst_offset, radeon_bo_size(dst_reloc->robj)); 3286 dst_offset, radeon_bo_size(dst_reloc->robj));