Blame SOURCES/0289-font-Harden-grub_font_blit_glyph-and-grub_font_blit_.patch

fd0330
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
fd0330
From: Zhang Boyang <zhangboyang.id@gmail.com>
fd0330
Date: Mon, 24 Oct 2022 07:15:41 +0800
fd0330
Subject: [PATCH] font: Harden grub_font_blit_glyph() and
fd0330
 grub_font_blit_glyph_mirror()
fd0330
fd0330
As a mitigation and hardening measure add sanity checks to
fd0330
grub_font_blit_glyph() and grub_font_blit_glyph_mirror(). This patch
fd0330
makes these two functions do nothing if target blitting area isn't fully
fd0330
contained in target bitmap. Therefore, if complex calculations in caller
fd0330
overflows and malicious coordinates are given, we are still safe because
fd0330
any coordinates which result in out-of-bound-write are rejected. However,
fd0330
this patch only checks for invalid coordinates, and doesn't provide any
fd0330
protection against invalid source glyph or destination glyph, e.g.
fd0330
mismatch between glyph size and buffer size.
fd0330
fd0330
This hardening measure is designed to mitigate possible overflows in
fd0330
blit_comb(). If overflow occurs, it may return invalid bounding box
fd0330
during dry run and call grub_font_blit_glyph() with malicious
fd0330
coordinates during actual blitting. However, we are still safe because
fd0330
the scratch glyph itself is valid, although its size makes no sense, and
fd0330
any invalid coordinates are rejected.
fd0330
fd0330
It would be better to call grub_fatal() if illegal parameter is detected.
fd0330
However, doing this may end up in a dangerous recursion because grub_fatal()
fd0330
would print messages to the screen and we are in the progress of drawing
fd0330
characters on the screen.
fd0330
fd0330
Reported-by: Daniel Axtens <dja@axtens.net>
fd0330
Signed-off-by: Zhang Boyang <zhangboyang.id@gmail.com>
fd0330
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
fd0330
(cherry picked from commit fcd7aa0c278f7cf3fb9f93f1a3966e1792339eb6)
fd0330
---
fd0330
 grub-core/font/font.c | 14 ++++++++++++++
fd0330
 1 file changed, 14 insertions(+)
fd0330
fd0330
diff --git a/grub-core/font/font.c b/grub-core/font/font.c
fd0330
index 12a5f0d08c..29fbb94294 100644
fd0330
--- a/grub-core/font/font.c
fd0330
+++ b/grub-core/font/font.c
fd0330
@@ -1069,8 +1069,15 @@ static void
fd0330
 grub_font_blit_glyph (struct grub_font_glyph *target,
fd0330
 		      struct grub_font_glyph *src, unsigned dx, unsigned dy)
fd0330
 {
fd0330
+  grub_uint16_t max_x, max_y;
fd0330
   unsigned src_bit, tgt_bit, src_byte, tgt_byte;
fd0330
   unsigned i, j;
fd0330
+
fd0330
+  /* Harden against out-of-bound writes. */
fd0330
+  if ((grub_add (dx, src->width, &max_x) || max_x > target->width) ||
fd0330
+      (grub_add (dy, src->height, &max_y) || max_y > target->height))
fd0330
+    return;
fd0330
+
fd0330
   for (i = 0; i < src->height; i++)
fd0330
     {
fd0330
       src_bit = (src->width * i) % 8;
fd0330
@@ -1102,9 +1109,16 @@ grub_font_blit_glyph_mirror (struct grub_font_glyph *target,
fd0330
 			     struct grub_font_glyph *src,
fd0330
 			     unsigned dx, unsigned dy)
fd0330
 {
fd0330
+  grub_uint16_t max_x, max_y;
fd0330
   unsigned tgt_bit, src_byte, tgt_byte;
fd0330
   signed src_bit;
fd0330
   unsigned i, j;
fd0330
+
fd0330
+  /* Harden against out-of-bound writes. */
fd0330
+  if ((grub_add (dx, src->width, &max_x) || max_x > target->width) ||
fd0330
+      (grub_add (dy, src->height, &max_y) || max_y > target->height))
fd0330
+    return;
fd0330
+
fd0330
   for (i = 0; i < src->height; i++)
fd0330
     {
fd0330
       src_bit = (src->width * i + src->width - 1) % 8;