You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
105 lines
3.1 KiB
105 lines
3.1 KiB
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 |
|
From: Andrei Borzenkov <arvidjaar@gmail.com> |
|
Date: Wed, 16 May 2018 13:06:04 -0400 |
|
Subject: [PATCH] efi/uga: use 64 bit for fb_base |
|
|
|
We get 64 bit from PCI BAR but then truncate by assigning to 32 bit. |
|
Make sure to check that pointer does not overflow on 32 bit platform. |
|
|
|
Closes: 50931 |
|
--- |
|
grub-core/video/efi_uga.c | 31 ++++++++++++++++--------------- |
|
1 file changed, 16 insertions(+), 15 deletions(-) |
|
|
|
diff --git a/grub-core/video/efi_uga.c b/grub-core/video/efi_uga.c |
|
index 464ede874da..1d4091c5631 100644 |
|
--- a/grub-core/video/efi_uga.c |
|
+++ b/grub-core/video/efi_uga.c |
|
@@ -34,7 +34,7 @@ GRUB_MOD_LICENSE ("GPLv3+"); |
|
|
|
static grub_efi_guid_t uga_draw_guid = GRUB_EFI_UGA_DRAW_GUID; |
|
static struct grub_efi_uga_draw_protocol *uga; |
|
-static grub_uint32_t uga_fb; |
|
+static grub_uint64_t uga_fb; |
|
static grub_uint32_t uga_pitch; |
|
|
|
static struct |
|
@@ -52,7 +52,7 @@ static struct |
|
#define FBTEST_COUNT 8 |
|
|
|
static int |
|
-find_line_len (grub_uint32_t *fb_base, grub_uint32_t *line_len) |
|
+find_line_len (grub_uint64_t *fb_base, grub_uint32_t *line_len) |
|
{ |
|
grub_uint32_t *base = (grub_uint32_t *) (grub_addr_t) *fb_base; |
|
int i; |
|
@@ -67,7 +67,7 @@ find_line_len (grub_uint32_t *fb_base, grub_uint32_t *line_len) |
|
{ |
|
if ((base[j] & RGB_MASK) == RGB_MAGIC) |
|
{ |
|
- *fb_base = (grub_uint32_t) (grub_addr_t) base; |
|
+ *fb_base = (grub_uint64_t) (grub_addr_t) base; |
|
*line_len = j << 2; |
|
|
|
return 1; |
|
@@ -84,7 +84,7 @@ find_line_len (grub_uint32_t *fb_base, grub_uint32_t *line_len) |
|
/* Context for find_framebuf. */ |
|
struct find_framebuf_ctx |
|
{ |
|
- grub_uint32_t *fb_base; |
|
+ grub_uint64_t *fb_base; |
|
grub_uint32_t *line_len; |
|
int found; |
|
}; |
|
@@ -120,7 +120,9 @@ find_card (grub_pci_device_t dev, grub_pci_id_t pciid, void *data) |
|
if (i == 5) |
|
break; |
|
|
|
- old_bar2 = grub_pci_read (addr + 4); |
|
+ i++; |
|
+ addr += 4; |
|
+ old_bar2 = grub_pci_read (addr); |
|
} |
|
else |
|
old_bar2 = 0; |
|
@@ -129,10 +131,15 @@ find_card (grub_pci_device_t dev, grub_pci_id_t pciid, void *data) |
|
base64 <<= 32; |
|
base64 |= (old_bar1 & GRUB_PCI_ADDR_MEM_MASK); |
|
|
|
- grub_dprintf ("fb", "%s(%d): 0x%llx\n", |
|
+ grub_dprintf ("fb", "%s(%d): 0x%" PRIxGRUB_UINT64_T "\n", |
|
((old_bar1 & GRUB_PCI_ADDR_MEM_PREFETCH) ? |
|
- "VMEM" : "MMIO"), i, |
|
- (unsigned long long) base64); |
|
+ "VMEM" : "MMIO"), type == GRUB_PCI_ADDR_MEM_TYPE_64 ? i - 1 : i, |
|
+ base64); |
|
+ |
|
+#if GRUB_CPU_SIZEOF_VOID_P == 4 |
|
+ if (old_bar2) |
|
+ continue; |
|
+#endif |
|
|
|
if ((old_bar1 & GRUB_PCI_ADDR_MEM_PREFETCH) && (! ctx->found)) |
|
{ |
|
@@ -140,12 +147,6 @@ find_card (grub_pci_device_t dev, grub_pci_id_t pciid, void *data) |
|
if (find_line_len (ctx->fb_base, ctx->line_len)) |
|
ctx->found++; |
|
} |
|
- |
|
- if (type == GRUB_PCI_ADDR_MEM_TYPE_64) |
|
- { |
|
- i++; |
|
- addr += 4; |
|
- } |
|
} |
|
} |
|
|
|
@@ -153,7 +154,7 @@ find_card (grub_pci_device_t dev, grub_pci_id_t pciid, void *data) |
|
} |
|
|
|
static int |
|
-find_framebuf (grub_uint32_t *fb_base, grub_uint32_t *line_len) |
|
+find_framebuf (grub_uint64_t *fb_base, grub_uint32_t *line_len) |
|
{ |
|
struct find_framebuf_ctx ctx = { |
|
.fb_base = fb_base,
|
|
|