0013-net-ip-Do-IP-fragment-maths-safely.patch 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. From cadde7e36b8797060ac8cdf7cca7d8e1e09697e6 Mon Sep 17 00:00:00 2001
  2. From: Daniel Axtens <dja@axtens.net>
  3. Date: Mon, 20 Dec 2021 19:41:21 +1100
  4. Subject: [PATCH] net/ip: Do IP fragment maths safely
  5. We can receive packets with invalid IP fragmentation information. This
  6. can lead to rsm->total_len underflowing and becoming very large.
  7. Then, in grub_netbuff_alloc(), we add to this very large number, which can
  8. cause it to overflow and wrap back around to a small positive number.
  9. The allocation then succeeds, but the resulting buffer is too small and
  10. subsequent operations can write past the end of the buffer.
  11. Catch the underflow here.
  12. Fixes: CVE-2022-28733
  13. Signed-off-by: Daniel Axtens <dja@axtens.net>
  14. Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
  15. Upstream: 3e4817538de828319ba6d59ced2fbb9b5ca13287
  16. Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
  17. ---
  18. grub-core/net/ip.c | 10 +++++++++-
  19. 1 file changed, 9 insertions(+), 1 deletion(-)
  20. diff --git a/grub-core/net/ip.c b/grub-core/net/ip.c
  21. index ea5edf8f1..74e4e8b06 100644
  22. --- a/grub-core/net/ip.c
  23. +++ b/grub-core/net/ip.c
  24. @@ -25,6 +25,7 @@
  25. #include <grub/net/netbuff.h>
  26. #include <grub/mm.h>
  27. #include <grub/priority_queue.h>
  28. +#include <grub/safemath.h>
  29. #include <grub/time.h>
  30. struct iphdr {
  31. @@ -512,7 +513,14 @@ grub_net_recv_ip4_packets (struct grub_net_buff *nb,
  32. {
  33. rsm->total_len = (8 * (grub_be_to_cpu16 (iph->frags) & OFFSET_MASK)
  34. + (nb->tail - nb->data));
  35. - rsm->total_len -= ((iph->verhdrlen & 0xf) * sizeof (grub_uint32_t));
  36. +
  37. + if (grub_sub (rsm->total_len, (iph->verhdrlen & 0xf) * sizeof (grub_uint32_t),
  38. + &rsm->total_len))
  39. + {
  40. + grub_dprintf ("net", "IP reassembly size underflow\n");
  41. + return GRUB_ERR_NONE;
  42. + }
  43. +
  44. rsm->asm_netbuff = grub_netbuff_alloc (rsm->total_len);
  45. if (!rsm->asm_netbuff)
  46. {
  47. --
  48. 2.41.0