Files
buildroot/boot/grub2/0056-net-Use-safe-math-macros-to-prevent-overflows.patch
Thomas Petazzoni ded3e0045a boot/grub2: add patches to fix numerous CVEs
This patch brings the entire stack of Debian patches on grub2 titled
"cve-2025-jan" and available at:

  https://salsa.debian.org/grub-team/grub/-/tree/debian/2.12-9/debian/patches/cve-2025-jan?ref_type=tags

As of this exact Debian grub2 version 2.12-9. Some minor conflicts had
to be fixed. All patches are in upstream Grub master, but mixed with
hundreds of other changes, which is why Debian's effort to backport
them has been leveraged here.

In addition to those patches, 2 extra patches are added:

 0073-net-drivers-ieee1275-ofnet-Add-missing-grub_malloc.patch
 0074-Constant-time-grub_crypto_memcmp.patch

The first one fixes an issue in one of the earlier patches. The fix is
not in Debian, but is in upstream Grub.

The second one fixes another CVE, not fixed in Debian, but fixed in
OpenSUSE. This fix is not upstream as upstream has decided to move to
libgcrypt instead to avoid the problem, but that's a fairly large
change.

Overall, this patch fixes all CVEs currently reported by pkg-stats
against our grub2 package, namely:

CVE-2024-45777
CVE-2024-45778
CVE-2024-45779
CVE-2024-45780
CVE-2024-45782
CVE-2024-56737
CVE-2024-56738
CVE-2025-0678
CVE-2025-0684
CVE-2025-0685
CVE-2025-0686
CVE-2025-0689
CVE-2025-1125

With the previous fixes on runtime tests added (to use glibc
toolchains to build grub2 tests), this commit successfully passes all
tests:

- The ISO9660 tests that use grub2:
  https://gitlab.com/tpetazzoni/buildroot/-/pipelines/1985234563

- The grub2 tests:
  https://gitlab.com/tpetazzoni/buildroot/-/pipelines/1985234685

Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
[Julien: also tested by building and booting
 - qemu_aarch64_sbsa_defconfig
 - qemu_arm_ebbr_defconfig
 - qemu_loongarch64_virt_efi_defconfig
 - qemu_riscv64_virt_efi_defconfig
 - pc_x86_64_bios_defconfig
 - pc_x86_64_efi_defconfig
]
Tested-by: Julien Olivain <ju.o@free.fr>
[Julien:
 - fix patch #72 upstream link to point to the initial patch
   sumbission rather than a reply
 - merge two _IGNORE_CVES blocks for patch #50 into a single one
 - order _IGNORE_CVES blocks by numerical patch order
 - order numerically the CVE list in commit log
 - add a "Fixes:" tag in patch #74 since its commit log does not
   mention the CVE.
]
Signed-off-by: Julien Olivain <ju.o@free.fr>
2025-08-19 02:50:55 +02:00

251 lines
7.6 KiB
Diff

From 6cb15ce33f7c7153ef986f3fe710e22062d37ba7 Mon Sep 17 00:00:00 2001
From: Lidong Chen <lidong.chen@oracle.com>
Date: Wed, 22 Jan 2025 18:04:42 +0000
Subject: [PATCH] net: Use safe math macros to prevent overflows
Replace direct arithmetic operations with macros from include/grub/safemath.h
to prevent potential overflow issues when calculating the memory sizes.
Signed-off-by: Lidong Chen <lidong.chen@oracle.com>
Signed-off-by: Alec Brown <alec.r.brown@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
Conflicts:
grub-core/net/bootp.c
grub-core/net/net.c
Upstream: 4beeff8a31c4fb4071d2225533cfa316b5a58391
Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
---
grub-core/net/bootp.c | 16 ++++++++--
grub-core/net/dns.c | 9 +++++-
grub-core/net/drivers/ieee1275/ofnet.c | 20 ++++++++++--
grub-core/net/net.c | 43 +++++++++++++++++++++-----
4 files changed, 75 insertions(+), 13 deletions(-)
diff --git a/grub-core/net/bootp.c b/grub-core/net/bootp.c
index abe45ef7b..2f45a3cc2 100644
--- a/grub-core/net/bootp.c
+++ b/grub-core/net/bootp.c
@@ -24,6 +24,7 @@
#include <grub/net/netbuff.h>
#include <grub/net/udp.h>
#include <grub/datetime.h>
+#include <grub/safemath.h>
struct grub_dhcp_discover_options
{
@@ -686,6 +687,7 @@ grub_cmd_dhcpopt (struct grub_command *cmd __attribute__ ((unused)),
unsigned num;
const grub_uint8_t *ptr;
grub_uint8_t taglength;
+ grub_uint8_t len;
if (argc < 4)
return grub_error (GRUB_ERR_BAD_ARGUMENT,
@@ -727,7 +729,12 @@ grub_cmd_dhcpopt (struct grub_command *cmd __attribute__ ((unused)),
if (grub_strcmp (args[3], "string") == 0)
{
grub_err_t err = GRUB_ERR_NONE;
- char *val = grub_malloc (taglength + 1);
+ char *val;
+
+ if (grub_add (taglength, 1, &len))
+ return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("tag length overflow"));
+
+ val = grub_malloc (len);
if (!val)
return grub_errno;
grub_memcpy (val, ptr, taglength);
@@ -760,7 +767,12 @@ grub_cmd_dhcpopt (struct grub_command *cmd __attribute__ ((unused)),
if (grub_strcmp (args[3], "hex") == 0)
{
grub_err_t err = GRUB_ERR_NONE;
- char *val = grub_malloc (2 * taglength + 1);
+ char *val;
+
+ if (grub_mul (taglength, 2, &len) || grub_add (len, 1, &len))
+ return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("tag length overflow"));
+
+ val = grub_malloc (len);
int i;
if (!val)
return grub_errno;
diff --git a/grub-core/net/dns.c b/grub-core/net/dns.c
index fcc09aa65..39b0c46cf 100644
--- a/grub-core/net/dns.c
+++ b/grub-core/net/dns.c
@@ -224,10 +224,17 @@ get_name (const grub_uint8_t *name_at, const grub_uint8_t *head,
{
int length;
char *ret;
+ int len;
if (!check_name_real (name_at, head, tail, NULL, &length, NULL))
return NULL;
- ret = grub_malloc (length + 1);
+
+ if (grub_add (length, 1, &len))
+ {
+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("name length overflow"));
+ return NULL;
+ }
+ ret = grub_malloc (len);
if (!ret)
return NULL;
if (!check_name_real (name_at, head, tail, NULL, NULL, ret))
diff --git a/grub-core/net/drivers/ieee1275/ofnet.c b/grub-core/net/drivers/ieee1275/ofnet.c
index 78f03df8e..c35b107ad 100644
--- a/grub-core/net/drivers/ieee1275/ofnet.c
+++ b/grub-core/net/drivers/ieee1275/ofnet.c
@@ -22,6 +22,7 @@
#include <grub/net.h>
#include <grub/time.h>
#include <grub/i18n.h>
+#include <grub/safemath.h>
GRUB_MOD_LICENSE ("GPLv3+");
@@ -391,6 +392,7 @@ search_net_devices (struct grub_ieee1275_devalias *alias)
grub_uint8_t *pprop;
char *shortname;
char need_suffix = 1;
+ grub_size_t sz;
if (grub_strcmp (alias->type, "network") != 0)
return 0;
@@ -448,9 +450,23 @@ search_net_devices (struct grub_ieee1275_devalias *alias)
}
if (need_suffix)
- ofdata->path = grub_malloc (grub_strlen (alias->path) + sizeof (SUFFIX));
+ {
+ if (grub_add (grub_strlen (alias->path), sizeof (SUFFIX), &sz))
+ {
+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow detected while obatining size of ofdata path"));
+ grub_print_error ();
+ return 0;
+ }
+ }
else
- ofdata->path = grub_malloc (grub_strlen (alias->path) + 1);
+ {
+ if (grub_add (grub_strlen (alias->path), 1, &sz))
+ {
+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow detected while obatining size of ofdata path"));
+ grub_print_error ();
+ return 0;
+ }
+ }
if (!ofdata->path)
{
grub_print_error ();
diff --git a/grub-core/net/net.c b/grub-core/net/net.c
index 2bd490279..27df4669a 100644
--- a/grub-core/net/net.c
+++ b/grub-core/net/net.c
@@ -32,6 +32,7 @@
#include <grub/loader.h>
#include <grub/bufio.h>
#include <grub/kernel.h>
+#include <grub/safemath.h>
GRUB_MOD_LICENSE ("GPLv3+");
@@ -206,6 +207,7 @@ grub_net_ipv6_get_slaac (struct grub_net_card *card,
{
struct grub_net_slaac_mac_list *slaac;
char *ptr;
+ grub_size_t sz;
for (slaac = card->slaac_list; slaac; slaac = slaac->next)
if (grub_net_hwaddr_cmp (&slaac->address, hwaddr) == 0)
@@ -215,9 +217,16 @@ grub_net_ipv6_get_slaac (struct grub_net_card *card,
if (!slaac)
return NULL;
- slaac->name = grub_malloc (grub_strlen (card->name)
- + GRUB_NET_MAX_STR_HWADDR_LEN
- + sizeof (":slaac"));
+ if (grub_add (grub_strlen (card->name),
+ (GRUB_NET_MAX_STR_HWADDR_LEN + sizeof (":slaac")), &sz))
+ {
+ grub_free (slaac);
+ grub_error (GRUB_ERR_OUT_OF_RANGE,
+ "overflow detected while obtaining size of slaac name");
+ return NULL;
+ }
+
+ slaac->name = grub_malloc (sz);
ptr = grub_stpcpy (slaac->name, card->name);
if (grub_net_hwaddr_cmp (&card->default_address, hwaddr) != 0)
{
@@ -288,6 +297,7 @@ grub_net_ipv6_get_link_local (struct grub_net_card *card,
char *name;
char *ptr;
grub_net_network_level_address_t addr;
+ grub_size_t sz;
addr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6;
addr.ipv6[0] = grub_cpu_to_be64_compile_time (0xfe80ULL << 48);
@@ -302,9 +312,14 @@ grub_net_ipv6_get_link_local (struct grub_net_card *card,
return inf;
}
- name = grub_malloc (grub_strlen (card->name)
- + GRUB_NET_MAX_STR_HWADDR_LEN
- + sizeof (":link"));
+ if (grub_add (grub_strlen (card->name),
+ (GRUB_NET_MAX_STR_HWADDR_LEN + sizeof (":link")), &sz))
+ {
+ grub_error (GRUB_ERR_OUT_OF_RANGE,
+ "overflow detected while obtaining size of link name");
+ return NULL;
+ }
+ name = grub_malloc (sz);
if (!name)
return NULL;
@@ -1435,9 +1450,15 @@ grub_net_open_real (const char *name)
if (grub_strchr (port_start + 1, ':'))
{
int iplen = grub_strlen (server);
+ grub_size_t sz;
/* Bracket bare IPv6 addr. */
- host = grub_malloc (iplen + 3);
+ if (grub_add (iplen, 3, &sz))
+ {
+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow detected while obtaining length of host"));
+ return NULL;
+ }
+ host = grub_malloc (sz);
if (!host)
return NULL;
@@ -1692,6 +1713,7 @@ grub_env_set_net_property (const char *intername, const char *suffix,
{
char *varname, *varvalue;
char *ptr;
+ grub_size_t sz;
varname = grub_xasprintf ("net_%s_%s", intername, suffix);
if (!varname)
@@ -1699,7 +1721,12 @@ grub_env_set_net_property (const char *intername, const char *suffix,
for (ptr = varname; *ptr; ptr++)
if (*ptr == ':')
*ptr = '_';
- varvalue = grub_malloc (len + 1);
+ if (grub_add (len, 1, &sz))
+ {
+ grub_free (varname);
+ return grub_error (GRUB_ERR_OUT_OF_RANGE, "overflow detected while obtaining the size of an env variable");
+ }
+ varvalue = grub_malloc (sz);
if (!varvalue)
{
grub_free (varname);
--
2.50.1