Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4d4e9907 authored by Ben Skeggs's avatar Ben Skeggs
Browse files

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



Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 1fe8c02f
Loading
Loading
Loading
Loading
+3 −4
Original line number Diff line number Diff line
@@ -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
+34 −0
Original line number Diff line number Diff line
@@ -27,6 +27,40 @@
#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)
{