drm/nouveau/bios: guard against out-of-bounds accesses to image
authorBen Skeggs <bskeggs@redhat.com>
Wed, 22 Jun 2016 02:10:00 +0000 (12:10 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Thu, 14 Jul 2016 01:53:25 +0000 (11:53 +1000)
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
drivers/gpu/drm/nouveau/include/nvkm/subdev/bios.h
drivers/gpu/drm/nouveau/nvkm/subdev/bios/base.c

index e39a1fea930beefa28d0ab5ac2400cb7181952ad..6137de829b8fbd10b830da023cfe152282653aec 100644 (file)
@@ -22,10 +22,9 @@ struct nvkm_bios {
 u8  nvbios_checksum(const u8 *data, int size);
 u16 nvbios_findstr(const u8 *data, int size, const char *str, int len);
 int nvbios_memcmp(struct nvkm_bios *, u32 addr, const char *, u32 len);
-
-#define nvbios_rd08(b,o) (b)->data[(o)]
-#define nvbios_rd16(b,o) get_unaligned_le16(&(b)->data[(o)])
-#define nvbios_rd32(b,o) get_unaligned_le32(&(b)->data[(o)])
+u8  nvbios_rd08(struct nvkm_bios *, u32 addr);
+u16 nvbios_rd16(struct nvkm_bios *, u32 addr);
+u32 nvbios_rd32(struct nvkm_bios *, u32 addr);
 
 int nvkm_bios_new(struct nvkm_device *, int, struct nvkm_bios **);
 #endif
index e15b9627b07e12cacca0bb671813d9d9e3b58628..db5fa009a6194e0f091a7186c4b5fb02f8f5c7ce 100644 (file)
 #include <subdev/bios/bmp.h>
 #include <subdev/bios/bit.h>
 
+static bool
+nvbios_addr(struct nvkm_bios *bios, u32 *addr, u8 size)
+{
+       if (unlikely(*addr + size >= bios->size)) {
+               nvkm_error(&bios->subdev, "OOB %d %08x\n", size, *addr);
+               return false;
+       }
+       return true;
+}
+
+u8
+nvbios_rd08(struct nvkm_bios *bios, u32 addr)
+{
+       if (likely(nvbios_addr(bios, &addr, 1)))
+               return bios->data[addr];
+       return 0x00;
+}
+
+u16
+nvbios_rd16(struct nvkm_bios *bios, u32 addr)
+{
+       if (likely(nvbios_addr(bios, &addr, 2)))
+               return get_unaligned_le16(&bios->data[addr]);
+       return 0x0000;
+}
+
+u32
+nvbios_rd32(struct nvkm_bios *bios, u32 addr)
+{
+       if (likely(nvbios_addr(bios, &addr, 4)))
+               return get_unaligned_le32(&bios->data[addr]);
+       return 0x00000000;
+}
+
 u8
 nvbios_checksum(const u8 *data, int size)
 {