Blame SOURCES/0270-efi-uga-use-64-bit-for-fb_base.patch

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