Browse Source

drm/nouveau/bios: guard against out-of-bounds accesses to image

Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Ben Skeggs 9 years ago
parent
commit
4d4e9907ff

+ 3 - 4
drivers/gpu/drm/nouveau/include/nvkm/subdev/bios.h

@@ -22,10 +22,9 @@ struct nvkm_bios {
 u8  nvbios_checksum(const u8 *data, int size);
 u8  nvbios_checksum(const u8 *data, int size);
 u16 nvbios_findstr(const u8 *data, int size, const char *str, int len);
 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);
 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 **);
 int nvkm_bios_new(struct nvkm_device *, int, struct nvkm_bios **);
 #endif
 #endif

+ 34 - 0
drivers/gpu/drm/nouveau/nvkm/subdev/bios/base.c

@@ -27,6 +27,40 @@
 #include <subdev/bios/bmp.h>
 #include <subdev/bios/bmp.h>
 #include <subdev/bios/bit.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
 u8
 nvbios_checksum(const u8 *data, int size)
 nvbios_checksum(const u8 *data, int size)
 {
 {