nalika / rpms / grub2

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