mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 10:40:15 +02:00 
			
		
		
		
	drm/nouveau/fbcon: fix out-of-bounds memory accesses
Reported by KASAN. Signed-off-by: Ben Skeggs <bskeggs@redhat.com> Cc: stable@vger.kernel.org
This commit is contained in:
		
							parent
							
								
									383d0a419f
								
							
						
					
					
						commit
						f045f459d9
					
				
					 4 changed files with 7 additions and 13 deletions
				
			
		| 
						 | 
					@ -552,6 +552,7 @@ nouveau_fbcon_init(struct drm_device *dev)
 | 
				
			||||||
	if (ret)
 | 
						if (ret)
 | 
				
			||||||
		goto fini;
 | 
							goto fini;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						fbcon->helper.fbdev->pixmap.buf_align = 4;
 | 
				
			||||||
	return 0;
 | 
						return 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fini:
 | 
					fini:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -82,7 +82,6 @@ nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
 | 
				
			||||||
	uint32_t fg;
 | 
						uint32_t fg;
 | 
				
			||||||
	uint32_t bg;
 | 
						uint32_t bg;
 | 
				
			||||||
	uint32_t dsize;
 | 
						uint32_t dsize;
 | 
				
			||||||
	uint32_t width;
 | 
					 | 
				
			||||||
	uint32_t *data = (uint32_t *)image->data;
 | 
						uint32_t *data = (uint32_t *)image->data;
 | 
				
			||||||
	int ret;
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -93,9 +92,6 @@ nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
 | 
				
			||||||
	if (ret)
 | 
						if (ret)
 | 
				
			||||||
		return ret;
 | 
							return ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	width = ALIGN(image->width, 8);
 | 
					 | 
				
			||||||
	dsize = ALIGN(width * image->height, 32) >> 5;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
 | 
						if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
 | 
				
			||||||
	    info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
 | 
						    info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
 | 
				
			||||||
		fg = ((uint32_t *) info->pseudo_palette)[image->fg_color];
 | 
							fg = ((uint32_t *) info->pseudo_palette)[image->fg_color];
 | 
				
			||||||
| 
						 | 
					@ -111,10 +107,11 @@ nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
 | 
				
			||||||
			 ((image->dx + image->width) & 0xffff));
 | 
								 ((image->dx + image->width) & 0xffff));
 | 
				
			||||||
	OUT_RING(chan, bg);
 | 
						OUT_RING(chan, bg);
 | 
				
			||||||
	OUT_RING(chan, fg);
 | 
						OUT_RING(chan, fg);
 | 
				
			||||||
	OUT_RING(chan, (image->height << 16) | width);
 | 
						OUT_RING(chan, (image->height << 16) | image->width);
 | 
				
			||||||
	OUT_RING(chan, (image->height << 16) | image->width);
 | 
						OUT_RING(chan, (image->height << 16) | image->width);
 | 
				
			||||||
	OUT_RING(chan, (image->dy << 16) | (image->dx & 0xffff));
 | 
						OUT_RING(chan, (image->dy << 16) | (image->dx & 0xffff));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dsize = ALIGN(image->width * image->height, 32) >> 5;
 | 
				
			||||||
	while (dsize) {
 | 
						while (dsize) {
 | 
				
			||||||
		int iter_len = dsize > 128 ? 128 : dsize;
 | 
							int iter_len = dsize > 128 ? 128 : dsize;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -95,7 +95,7 @@ nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
 | 
				
			||||||
	struct nouveau_fbdev *nfbdev = info->par;
 | 
						struct nouveau_fbdev *nfbdev = info->par;
 | 
				
			||||||
	struct nouveau_drm *drm = nouveau_drm(nfbdev->dev);
 | 
						struct nouveau_drm *drm = nouveau_drm(nfbdev->dev);
 | 
				
			||||||
	struct nouveau_channel *chan = drm->channel;
 | 
						struct nouveau_channel *chan = drm->channel;
 | 
				
			||||||
	uint32_t width, dwords, *data = (uint32_t *)image->data;
 | 
						uint32_t dwords, *data = (uint32_t *)image->data;
 | 
				
			||||||
	uint32_t mask = ~(~0 >> (32 - info->var.bits_per_pixel));
 | 
						uint32_t mask = ~(~0 >> (32 - info->var.bits_per_pixel));
 | 
				
			||||||
	uint32_t *palette = info->pseudo_palette;
 | 
						uint32_t *palette = info->pseudo_palette;
 | 
				
			||||||
	int ret;
 | 
						int ret;
 | 
				
			||||||
| 
						 | 
					@ -107,9 +107,6 @@ nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
 | 
				
			||||||
	if (ret)
 | 
						if (ret)
 | 
				
			||||||
		return ret;
 | 
							return ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	width = ALIGN(image->width, 32);
 | 
					 | 
				
			||||||
	dwords = (width * image->height) >> 5;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	BEGIN_NV04(chan, NvSub2D, 0x0814, 2);
 | 
						BEGIN_NV04(chan, NvSub2D, 0x0814, 2);
 | 
				
			||||||
	if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
 | 
						if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
 | 
				
			||||||
	    info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
 | 
						    info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
 | 
				
			||||||
| 
						 | 
					@ -128,6 +125,7 @@ nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
 | 
				
			||||||
	OUT_RING(chan, 0);
 | 
						OUT_RING(chan, 0);
 | 
				
			||||||
	OUT_RING(chan, image->dy);
 | 
						OUT_RING(chan, image->dy);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dwords = ALIGN(image->width * image->height, 32) >> 5;
 | 
				
			||||||
	while (dwords) {
 | 
						while (dwords) {
 | 
				
			||||||
		int push = dwords > 2047 ? 2047 : dwords;
 | 
							int push = dwords > 2047 ? 2047 : dwords;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -95,7 +95,7 @@ nvc0_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
 | 
				
			||||||
	struct nouveau_fbdev *nfbdev = info->par;
 | 
						struct nouveau_fbdev *nfbdev = info->par;
 | 
				
			||||||
	struct nouveau_drm *drm = nouveau_drm(nfbdev->dev);
 | 
						struct nouveau_drm *drm = nouveau_drm(nfbdev->dev);
 | 
				
			||||||
	struct nouveau_channel *chan = drm->channel;
 | 
						struct nouveau_channel *chan = drm->channel;
 | 
				
			||||||
	uint32_t width, dwords, *data = (uint32_t *)image->data;
 | 
						uint32_t dwords, *data = (uint32_t *)image->data;
 | 
				
			||||||
	uint32_t mask = ~(~0 >> (32 - info->var.bits_per_pixel));
 | 
						uint32_t mask = ~(~0 >> (32 - info->var.bits_per_pixel));
 | 
				
			||||||
	uint32_t *palette = info->pseudo_palette;
 | 
						uint32_t *palette = info->pseudo_palette;
 | 
				
			||||||
	int ret;
 | 
						int ret;
 | 
				
			||||||
| 
						 | 
					@ -107,9 +107,6 @@ nvc0_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
 | 
				
			||||||
	if (ret)
 | 
						if (ret)
 | 
				
			||||||
		return ret;
 | 
							return ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	width = ALIGN(image->width, 32);
 | 
					 | 
				
			||||||
	dwords = (width * image->height) >> 5;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	BEGIN_NVC0(chan, NvSub2D, 0x0814, 2);
 | 
						BEGIN_NVC0(chan, NvSub2D, 0x0814, 2);
 | 
				
			||||||
	if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
 | 
						if (info->fix.visual == FB_VISUAL_TRUECOLOR ||
 | 
				
			||||||
	    info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
 | 
						    info->fix.visual == FB_VISUAL_DIRECTCOLOR) {
 | 
				
			||||||
| 
						 | 
					@ -128,6 +125,7 @@ nvc0_fbcon_imageblit(struct fb_info *info, const struct fb_image *image)
 | 
				
			||||||
	OUT_RING  (chan, 0);
 | 
						OUT_RING  (chan, 0);
 | 
				
			||||||
	OUT_RING  (chan, image->dy);
 | 
						OUT_RING  (chan, image->dy);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						dwords = ALIGN(image->width * image->height, 32) >> 5;
 | 
				
			||||||
	while (dwords) {
 | 
						while (dwords) {
 | 
				
			||||||
		int push = dwords > 2047 ? 2047 : dwords;
 | 
							int push = dwords > 2047 ? 2047 : dwords;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue