blob: 8bf9090f944aeb5c4f5a91539c1369ea4a100bb3 [file] [log] [blame]
Patrick Williams92b42cb2022-09-03 06:53:57 -05001From 3e4817538de828319ba6d59ced2fbb9b5ca13287 Mon Sep 17 00:00:00 2001
2From: Daniel Axtens <dja@axtens.net>
3Date: Mon, 20 Dec 2021 19:41:21 +1100
4Subject: [PATCH] net/ip: Do IP fragment maths safely
5
6We can receive packets with invalid IP fragmentation information. This
7can lead to rsm->total_len underflowing and becoming very large.
8
9Then, in grub_netbuff_alloc(), we add to this very large number, which can
10cause it to overflow and wrap back around to a small positive number.
11The allocation then succeeds, but the resulting buffer is too small and
12subsequent operations can write past the end of the buffer.
13
14Catch the underflow here.
15
16Fixes: CVE-2022-28733
17
18Signed-off-by: Daniel Axtens <dja@axtens.net>
19Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
20
21Upstream-Status: Backport
22CVE: CVE-2022-28733
23
24Reference to upstream patch:
25https://git.savannah.gnu.org/cgit/grub.git/commit/?id=3e4817538de828319ba6d59ced2fbb9b5ca13287
26
27Signed-off-by: Yongxin Liu <yongxin.liu@windriver.com>
28
29---
30 grub-core/net/ip.c | 10 +++++++++-
31 1 file changed, 9 insertions(+), 1 deletion(-)
32
33diff --git a/grub-core/net/ip.c b/grub-core/net/ip.c
34index e3d62e97f..3c3d0be0e 100644
35--- a/grub-core/net/ip.c
36+++ b/grub-core/net/ip.c
37@@ -25,6 +25,7 @@
38 #include <grub/net/netbuff.h>
39 #include <grub/mm.h>
40 #include <grub/priority_queue.h>
41+#include <grub/safemath.h>
42 #include <grub/time.h>
43
44 struct iphdr {
45@@ -512,7 +513,14 @@ grub_net_recv_ip4_packets (struct grub_net_buff *nb,
46 {
47 rsm->total_len = (8 * (grub_be_to_cpu16 (iph->frags) & OFFSET_MASK)
48 + (nb->tail - nb->data));
49- rsm->total_len -= ((iph->verhdrlen & 0xf) * sizeof (grub_uint32_t));
50+
51+ if (grub_sub (rsm->total_len, (iph->verhdrlen & 0xf) * sizeof (grub_uint32_t),
52+ &rsm->total_len))
53+ {
54+ grub_dprintf ("net", "IP reassembly size underflow\n");
55+ return GRUB_ERR_NONE;
56+ }
57+
58 rsm->asm_netbuff = grub_netbuff_alloc (rsm->total_len);
59 if (!rsm->asm_netbuff)
60 {
61--
622.34.1
63