2
1

0023-script-execute-Limit-the-recursion-depth.patch 2.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960
  1. From 2a094a7116c56519a42a13c96e77bdeda6069076 Mon Sep 17 00:00:00 2001
  2. From: B Horn <b@horn.uk>
  3. Date: Thu, 18 Apr 2024 19:04:13 +0100
  4. Subject: [PATCH] script/execute: Limit the recursion depth
  5. If unbounded recursion is allowed it becomes possible to collide the
  6. stack with the heap. As UEFI firmware often lacks guard pages this
  7. becomes an exploitable issue as it is possible in some cases to do
  8. a controlled overwrite of a section of this heap region with
  9. arbitrary data.
  10. Reported-by: B Horn <b@horn.uk>
  11. Signed-off-by: B Horn <b@horn.uk>
  12. Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
  13. Upstream: d8a937ccae5c6d86dc4375698afca5cefdcd01e1
  14. Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
  15. ---
  16. grub-core/script/execute.c | 14 ++++++++++++++
  17. 1 file changed, 14 insertions(+)
  18. diff --git a/grub-core/script/execute.c b/grub-core/script/execute.c
  19. index 14ff09094..e1450f45d 100644
  20. --- a/grub-core/script/execute.c
  21. +++ b/grub-core/script/execute.c
  22. @@ -33,10 +33,18 @@
  23. is sizeof (int) * 3, and one extra for a possible -ve sign. */
  24. #define ERRNO_DIGITS_MAX (sizeof (int) * 3 + 1)
  25. +/*
  26. + * A limit on recursion, to avoid colliding with the heap. UEFI defines a baseline
  27. + * stack size of 128 KiB. So, assuming at most 1-2 KiB per iteration this should
  28. + * keep us safe.
  29. + */
  30. +#define MAX_RECURSION_DEPTH 64
  31. +
  32. static unsigned long is_continue;
  33. static unsigned long active_loops;
  34. static unsigned long active_breaks;
  35. static unsigned long function_return;
  36. +static unsigned long recursion_depth;
  37. #define GRUB_SCRIPT_SCOPE_MALLOCED 1
  38. #define GRUB_SCRIPT_SCOPE_ARGS_MALLOCED 2
  39. @@ -816,7 +824,13 @@ grub_script_execute_cmd (struct grub_script_cmd *cmd)
  40. if (cmd == 0)
  41. return 0;
  42. + recursion_depth++;
  43. +
  44. + if (recursion_depth >= MAX_RECURSION_DEPTH)
  45. + return grub_error (GRUB_ERR_RECURSION_DEPTH, N_("maximum recursion depth exceeded"));
  46. +
  47. ret = cmd->exec (cmd);
  48. + recursion_depth--;
  49. grub_snprintf (errnobuf, sizeof (errnobuf), "%d", ret);
  50. grub_env_set ("?", errnobuf);
  51. --
  52. 2.50.1