summaryrefslogtreecommitdiffstats
path: root/debian/patches/0081-net-dns-Don-t-read-past-the-end-of-the-string-we-re-.patch
diff options
context:
space:
mode:
Diffstat (limited to 'debian/patches/0081-net-dns-Don-t-read-past-the-end-of-the-string-we-re-.patch')
-rw-r--r--debian/patches/0081-net-dns-Don-t-read-past-the-end-of-the-string-we-re-.patch69
1 files changed, 69 insertions, 0 deletions
diff --git a/debian/patches/0081-net-dns-Don-t-read-past-the-end-of-the-string-we-re-.patch b/debian/patches/0081-net-dns-Don-t-read-past-the-end-of-the-string-we-re-.patch
new file mode 100644
index 0000000..0fc28a9
--- /dev/null
+++ b/debian/patches/0081-net-dns-Don-t-read-past-the-end-of-the-string-we-re-.patch
@@ -0,0 +1,69 @@
+From 968febf3a4de5df0f91cc13bc6b6053fc22575e1 Mon Sep 17 00:00:00 2001
+From: Daniel Axtens <dja@axtens.net>
+Date: Mon, 20 Dec 2021 21:55:43 +1100
+Subject: net/dns: Don't read past the end of the string we're checking against
+
+I don't really understand what's going on here but fuzzing found
+a bug where we read past the end of check_with. That's a C string,
+so use grub_strlen() to make sure we don't overread it.
+
+Signed-off-by: Daniel Axtens <dja@axtens.net>
+Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
+---
+ grub-core/net/dns.c | 19 ++++++++++++++++---
+ 1 file changed, 16 insertions(+), 3 deletions(-)
+
+diff --git a/grub-core/net/dns.c b/grub-core/net/dns.c
+index 135faac03..17961a9f1 100644
+--- a/grub-core/net/dns.c
++++ b/grub-core/net/dns.c
+@@ -146,11 +146,18 @@ check_name_real (const grub_uint8_t *name_at, const grub_uint8_t *head,
+ int *length, char *set)
+ {
+ const char *readable_ptr = check_with;
++ int readable_len;
+ const grub_uint8_t *ptr;
+ char *optr = set;
+ int bytes_processed = 0;
+ if (length)
+ *length = 0;
++
++ if (readable_ptr != NULL)
++ readable_len = grub_strlen (readable_ptr);
++ else
++ readable_len = 0;
++
+ for (ptr = name_at; ptr < tail && bytes_processed < tail - head + 2; )
+ {
+ /* End marker. */
+@@ -172,13 +179,16 @@ check_name_real (const grub_uint8_t *name_at, const grub_uint8_t *head,
+ ptr = head + (((ptr[0] & 0x3f) << 8) | ptr[1]);
+ continue;
+ }
+- if (readable_ptr && grub_memcmp (ptr + 1, readable_ptr, *ptr) != 0)
++ if (readable_ptr != NULL && (*ptr > readable_len || grub_memcmp (ptr + 1, readable_ptr, *ptr) != 0))
+ return 0;
+ if (grub_memchr (ptr + 1, 0, *ptr)
+ || grub_memchr (ptr + 1, '.', *ptr))
+ return 0;
+ if (readable_ptr)
+- readable_ptr += *ptr;
++ {
++ readable_ptr += *ptr;
++ readable_len -= *ptr;
++ }
+ if (readable_ptr && *readable_ptr != '.' && *readable_ptr != 0)
+ return 0;
+ bytes_processed += *ptr + 1;
+@@ -192,7 +202,10 @@ check_name_real (const grub_uint8_t *name_at, const grub_uint8_t *head,
+ if (optr)
+ *optr++ = '.';
+ if (readable_ptr && *readable_ptr)
+- readable_ptr++;
++ {
++ readable_ptr++;
++ readable_len--;
++ }
+ ptr += *ptr + 1;
+ }
+ return 0;