grub-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[SECURITY PATCH 11/13] font: Harden grub_font_blit_glyph() and grub_font


From: Daniel Kiper
Subject: [SECURITY PATCH 11/13] font: Harden grub_font_blit_glyph() and grub_font_blit_glyph_mirror()
Date: Tue, 15 Nov 2022 19:01:08 +0100

From: Zhang Boyang <zhangboyang.id@gmail.com>

As a mitigation and hardening measure add sanity checks to
grub_font_blit_glyph() and grub_font_blit_glyph_mirror(). This patch
makes these two functions do nothing if target blitting area isn't fully
contained in target bitmap. Therefore, if complex calculations in caller
overflows and malicious coordinates are given, we are still safe because
any coordinates which result in out-of-bound-write are rejected. However,
this patch only checks for invalid coordinates, and doesn't provide any
protection against invalid source glyph or destination glyph, e.g.
mismatch between glyph size and buffer size.

This hardening measure is designed to mitigate possible overflows in
blit_comb(). If overflow occurs, it may return invalid bounding box
during dry run and call grub_font_blit_glyph() with malicious
coordinates during actual blitting. However, we are still safe because
the scratch glyph itself is valid, although its size makes no sense, and
any invalid coordinates are rejected.

It would be better to call grub_fatal() if illegal parameter is detected.
However, doing this may end up in a dangerous recursion because grub_fatal()
would print messages to the screen and we are in the progress of drawing
characters on the screen.

Reported-by: Daniel Axtens <dja@axtens.net>
Signed-off-by: Zhang Boyang <zhangboyang.id@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
 grub-core/font/font.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/grub-core/font/font.c b/grub-core/font/font.c
index 3d3d803e8..cf15dc2f9 100644
--- a/grub-core/font/font.c
+++ b/grub-core/font/font.c
@@ -1069,8 +1069,15 @@ static void
 grub_font_blit_glyph (struct grub_font_glyph *target,
                      struct grub_font_glyph *src, unsigned dx, unsigned dy)
 {
+  grub_uint16_t max_x, max_y;
   unsigned src_bit, tgt_bit, src_byte, tgt_byte;
   unsigned i, j;
+
+  /* Harden against out-of-bound writes. */
+  if ((grub_add (dx, src->width, &max_x) || max_x > target->width) ||
+      (grub_add (dy, src->height, &max_y) || max_y > target->height))
+    return;
+
   for (i = 0; i < src->height; i++)
     {
       src_bit = (src->width * i) % 8;
@@ -1102,9 +1109,16 @@ grub_font_blit_glyph_mirror (struct grub_font_glyph 
*target,
                             struct grub_font_glyph *src,
                             unsigned dx, unsigned dy)
 {
+  grub_uint16_t max_x, max_y;
   unsigned tgt_bit, src_byte, tgt_byte;
   signed src_bit;
   unsigned i, j;
+
+  /* Harden against out-of-bound writes. */
+  if ((grub_add (dx, src->width, &max_x) || max_x > target->width) ||
+      (grub_add (dy, src->height, &max_y) || max_y > target->height))
+    return;
+
   for (i = 0; i < src->height; i++)
     {
       src_bit = (src->width * i + src->width - 1) % 8;
-- 
2.11.0




reply via email to

[Prev in Thread] Current Thread [Next in Thread]