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

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