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

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