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