8631a2
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
8631a2
From: Andrei Borzenkov <arvidjaar@gmail.com>
8631a2
Date: Wed, 16 May 2018 13:06:04 -0400
8631a2
Subject: [PATCH] efi/uga: use 64 bit for fb_base
8631a2
8631a2
We get 64 bit from PCI BAR but then truncate by assigning to 32 bit.
8631a2
Make sure to check that pointer does not overflow on 32 bit platform.
8631a2
8631a2
Closes: 50931
8631a2
---
8631a2
 grub-core/video/efi_uga.c | 31 ++++++++++++++++---------------
8631a2
 1 file changed, 16 insertions(+), 15 deletions(-)
8631a2
8631a2
diff --git a/grub-core/video/efi_uga.c b/grub-core/video/efi_uga.c
b32e65
index 044af1d20..97a607c01 100644
8631a2
--- a/grub-core/video/efi_uga.c
8631a2
+++ b/grub-core/video/efi_uga.c
8631a2
@@ -34,7 +34,7 @@ GRUB_MOD_LICENSE ("GPLv3+");
8631a2
 
8631a2
 static grub_efi_guid_t uga_draw_guid = GRUB_EFI_UGA_DRAW_GUID;
8631a2
 static struct grub_efi_uga_draw_protocol *uga;
8631a2
-static grub_uint32_t uga_fb;
8631a2
+static grub_uint64_t uga_fb;
8631a2
 static grub_uint32_t uga_pitch;
8631a2
 
8631a2
 static struct
8631a2
@@ -52,7 +52,7 @@ static struct
8631a2
 #define FBTEST_COUNT	8
8631a2
 
8631a2
 static int
8631a2
-find_line_len (grub_uint32_t *fb_base, grub_uint32_t *line_len)
8631a2
+find_line_len (grub_uint64_t *fb_base, grub_uint32_t *line_len)
8631a2
 {
8631a2
   grub_uint32_t *base = (grub_uint32_t *) (grub_addr_t) *fb_base;
8631a2
   int i;
8631a2
@@ -67,7 +67,7 @@ find_line_len (grub_uint32_t *fb_base, grub_uint32_t *line_len)
8631a2
 	    {
8631a2
 	      if ((base[j] & RGB_MASK) == RGB_MAGIC)
8631a2
 		{
8631a2
-		  *fb_base = (grub_uint32_t) (grub_addr_t) base;
8631a2
+		  *fb_base = (grub_uint64_t) (grub_addr_t) base;
8631a2
 		  *line_len = j << 2;
8631a2
 
8631a2
 		  return 1;
8631a2
@@ -84,7 +84,7 @@ find_line_len (grub_uint32_t *fb_base, grub_uint32_t *line_len)
8631a2
 /* Context for find_framebuf.  */
8631a2
 struct find_framebuf_ctx
8631a2
 {
8631a2
-  grub_uint32_t *fb_base;
8631a2
+  grub_uint64_t *fb_base;
8631a2
   grub_uint32_t *line_len;
8631a2
   int found;
8631a2
 };
8631a2
@@ -129,7 +129,9 @@ find_card (grub_pci_device_t dev, grub_pci_id_t pciid, void *data)
8631a2
 	      if (i == 5)
8631a2
 		break;
8631a2
 
8631a2
-	      old_bar2 = grub_pci_read (addr + 4);
8631a2
+	      i++;
8631a2
+	      addr += 4;
8631a2
+	      old_bar2 = grub_pci_read (addr);
8631a2
 	    }
8631a2
 	  else
8631a2
 	    old_bar2 = 0;
8631a2
@@ -138,10 +140,15 @@ find_card (grub_pci_device_t dev, grub_pci_id_t pciid, void *data)
8631a2
 	  base64 <<= 32;
8631a2
 	  base64 |= (old_bar1 & GRUB_PCI_ADDR_MEM_MASK);
8631a2
 
8631a2
-	  grub_dprintf ("fb", "%s(%d): 0x%llx\n",
8631a2
+	  grub_dprintf ("fb", "%s(%d): 0x%" PRIxGRUB_UINT64_T "\n",
8631a2
 			((old_bar1 & GRUB_PCI_ADDR_MEM_PREFETCH) ?
8631a2
-			"VMEM" : "MMIO"), i,
8631a2
-		       (unsigned long long) base64);
8631a2
+			"VMEM" : "MMIO"), type == GRUB_PCI_ADDR_MEM_TYPE_64 ? i - 1 : i,
8631a2
+			base64);
8631a2
+
8631a2
+#if GRUB_CPU_SIZEOF_VOID_P == 4
8631a2
+	  if (old_bar2)
8631a2
+	    continue;
8631a2
+#endif
8631a2
 
8631a2
 	  if ((old_bar1 & GRUB_PCI_ADDR_MEM_PREFETCH) && (! ctx->found))
8631a2
 	    {
8631a2
@@ -149,12 +156,6 @@ find_card (grub_pci_device_t dev, grub_pci_id_t pciid, void *data)
8631a2
 	      if (find_line_len (ctx->fb_base, ctx->line_len))
8631a2
 		ctx->found++;
8631a2
 	    }
8631a2
-
8631a2
-	  if (type == GRUB_PCI_ADDR_MEM_TYPE_64)
8631a2
-	    {
8631a2
-	      i++;
8631a2
-	      addr += 4;
8631a2
-	    }
8631a2
 	}
8631a2
     }
8631a2
 
8631a2
@@ -162,7 +163,7 @@ find_card (grub_pci_device_t dev, grub_pci_id_t pciid, void *data)
8631a2
 }
8631a2
 
8631a2
 static int
8631a2
-find_framebuf (grub_uint32_t *fb_base, grub_uint32_t *line_len)
8631a2
+find_framebuf (grub_uint64_t *fb_base, grub_uint32_t *line_len)
8631a2
 {
8631a2
   struct find_framebuf_ctx ctx = {
8631a2
     .fb_base = fb_base,