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

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