0056-net-Use-safe-math-macros-to-prevent-overflows.patch 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250
  1. From 6cb15ce33f7c7153ef986f3fe710e22062d37ba7 Mon Sep 17 00:00:00 2001
  2. From: Lidong Chen <lidong.chen@oracle.com>
  3. Date: Wed, 22 Jan 2025 18:04:42 +0000
  4. Subject: [PATCH] net: Use safe math macros to prevent overflows
  5. Replace direct arithmetic operations with macros from include/grub/safemath.h
  6. to prevent potential overflow issues when calculating the memory sizes.
  7. Signed-off-by: Lidong Chen <lidong.chen@oracle.com>
  8. Signed-off-by: Alec Brown <alec.r.brown@oracle.com>
  9. Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
  10. Conflicts:
  11. grub-core/net/bootp.c
  12. grub-core/net/net.c
  13. Upstream: 4beeff8a31c4fb4071d2225533cfa316b5a58391
  14. Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
  15. ---
  16. grub-core/net/bootp.c | 16 ++++++++--
  17. grub-core/net/dns.c | 9 +++++-
  18. grub-core/net/drivers/ieee1275/ofnet.c | 20 ++++++++++--
  19. grub-core/net/net.c | 43 +++++++++++++++++++++-----
  20. 4 files changed, 75 insertions(+), 13 deletions(-)
  21. diff --git a/grub-core/net/bootp.c b/grub-core/net/bootp.c
  22. index abe45ef7b..2f45a3cc2 100644
  23. --- a/grub-core/net/bootp.c
  24. +++ b/grub-core/net/bootp.c
  25. @@ -24,6 +24,7 @@
  26. #include <grub/net/netbuff.h>
  27. #include <grub/net/udp.h>
  28. #include <grub/datetime.h>
  29. +#include <grub/safemath.h>
  30. struct grub_dhcp_discover_options
  31. {
  32. @@ -686,6 +687,7 @@ grub_cmd_dhcpopt (struct grub_command *cmd __attribute__ ((unused)),
  33. unsigned num;
  34. const grub_uint8_t *ptr;
  35. grub_uint8_t taglength;
  36. + grub_uint8_t len;
  37. if (argc < 4)
  38. return grub_error (GRUB_ERR_BAD_ARGUMENT,
  39. @@ -727,7 +729,12 @@ grub_cmd_dhcpopt (struct grub_command *cmd __attribute__ ((unused)),
  40. if (grub_strcmp (args[3], "string") == 0)
  41. {
  42. grub_err_t err = GRUB_ERR_NONE;
  43. - char *val = grub_malloc (taglength + 1);
  44. + char *val;
  45. +
  46. + if (grub_add (taglength, 1, &len))
  47. + return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("tag length overflow"));
  48. +
  49. + val = grub_malloc (len);
  50. if (!val)
  51. return grub_errno;
  52. grub_memcpy (val, ptr, taglength);
  53. @@ -760,7 +767,12 @@ grub_cmd_dhcpopt (struct grub_command *cmd __attribute__ ((unused)),
  54. if (grub_strcmp (args[3], "hex") == 0)
  55. {
  56. grub_err_t err = GRUB_ERR_NONE;
  57. - char *val = grub_malloc (2 * taglength + 1);
  58. + char *val;
  59. +
  60. + if (grub_mul (taglength, 2, &len) || grub_add (len, 1, &len))
  61. + return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("tag length overflow"));
  62. +
  63. + val = grub_malloc (len);
  64. int i;
  65. if (!val)
  66. return grub_errno;
  67. diff --git a/grub-core/net/dns.c b/grub-core/net/dns.c
  68. index fcc09aa65..39b0c46cf 100644
  69. --- a/grub-core/net/dns.c
  70. +++ b/grub-core/net/dns.c
  71. @@ -224,10 +224,17 @@ get_name (const grub_uint8_t *name_at, const grub_uint8_t *head,
  72. {
  73. int length;
  74. char *ret;
  75. + int len;
  76. if (!check_name_real (name_at, head, tail, NULL, &length, NULL))
  77. return NULL;
  78. - ret = grub_malloc (length + 1);
  79. +
  80. + if (grub_add (length, 1, &len))
  81. + {
  82. + grub_error (GRUB_ERR_OUT_OF_RANGE, N_("name length overflow"));
  83. + return NULL;
  84. + }
  85. + ret = grub_malloc (len);
  86. if (!ret)
  87. return NULL;
  88. if (!check_name_real (name_at, head, tail, NULL, NULL, ret))
  89. diff --git a/grub-core/net/drivers/ieee1275/ofnet.c b/grub-core/net/drivers/ieee1275/ofnet.c
  90. index 78f03df8e..c35b107ad 100644
  91. --- a/grub-core/net/drivers/ieee1275/ofnet.c
  92. +++ b/grub-core/net/drivers/ieee1275/ofnet.c
  93. @@ -22,6 +22,7 @@
  94. #include <grub/net.h>
  95. #include <grub/time.h>
  96. #include <grub/i18n.h>
  97. +#include <grub/safemath.h>
  98. GRUB_MOD_LICENSE ("GPLv3+");
  99. @@ -391,6 +392,7 @@ search_net_devices (struct grub_ieee1275_devalias *alias)
  100. grub_uint8_t *pprop;
  101. char *shortname;
  102. char need_suffix = 1;
  103. + grub_size_t sz;
  104. if (grub_strcmp (alias->type, "network") != 0)
  105. return 0;
  106. @@ -448,9 +450,23 @@ search_net_devices (struct grub_ieee1275_devalias *alias)
  107. }
  108. if (need_suffix)
  109. - ofdata->path = grub_malloc (grub_strlen (alias->path) + sizeof (SUFFIX));
  110. + {
  111. + if (grub_add (grub_strlen (alias->path), sizeof (SUFFIX), &sz))
  112. + {
  113. + grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow detected while obatining size of ofdata path"));
  114. + grub_print_error ();
  115. + return 0;
  116. + }
  117. + }
  118. else
  119. - ofdata->path = grub_malloc (grub_strlen (alias->path) + 1);
  120. + {
  121. + if (grub_add (grub_strlen (alias->path), 1, &sz))
  122. + {
  123. + grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow detected while obatining size of ofdata path"));
  124. + grub_print_error ();
  125. + return 0;
  126. + }
  127. + }
  128. if (!ofdata->path)
  129. {
  130. grub_print_error ();
  131. diff --git a/grub-core/net/net.c b/grub-core/net/net.c
  132. index 2bd490279..27df4669a 100644
  133. --- a/grub-core/net/net.c
  134. +++ b/grub-core/net/net.c
  135. @@ -32,6 +32,7 @@
  136. #include <grub/loader.h>
  137. #include <grub/bufio.h>
  138. #include <grub/kernel.h>
  139. +#include <grub/safemath.h>
  140. GRUB_MOD_LICENSE ("GPLv3+");
  141. @@ -206,6 +207,7 @@ grub_net_ipv6_get_slaac (struct grub_net_card *card,
  142. {
  143. struct grub_net_slaac_mac_list *slaac;
  144. char *ptr;
  145. + grub_size_t sz;
  146. for (slaac = card->slaac_list; slaac; slaac = slaac->next)
  147. if (grub_net_hwaddr_cmp (&slaac->address, hwaddr) == 0)
  148. @@ -215,9 +217,16 @@ grub_net_ipv6_get_slaac (struct grub_net_card *card,
  149. if (!slaac)
  150. return NULL;
  151. - slaac->name = grub_malloc (grub_strlen (card->name)
  152. - + GRUB_NET_MAX_STR_HWADDR_LEN
  153. - + sizeof (":slaac"));
  154. + if (grub_add (grub_strlen (card->name),
  155. + (GRUB_NET_MAX_STR_HWADDR_LEN + sizeof (":slaac")), &sz))
  156. + {
  157. + grub_free (slaac);
  158. + grub_error (GRUB_ERR_OUT_OF_RANGE,
  159. + "overflow detected while obtaining size of slaac name");
  160. + return NULL;
  161. + }
  162. +
  163. + slaac->name = grub_malloc (sz);
  164. ptr = grub_stpcpy (slaac->name, card->name);
  165. if (grub_net_hwaddr_cmp (&card->default_address, hwaddr) != 0)
  166. {
  167. @@ -288,6 +297,7 @@ grub_net_ipv6_get_link_local (struct grub_net_card *card,
  168. char *name;
  169. char *ptr;
  170. grub_net_network_level_address_t addr;
  171. + grub_size_t sz;
  172. addr.type = GRUB_NET_NETWORK_LEVEL_PROTOCOL_IPV6;
  173. addr.ipv6[0] = grub_cpu_to_be64_compile_time (0xfe80ULL << 48);
  174. @@ -302,9 +312,14 @@ grub_net_ipv6_get_link_local (struct grub_net_card *card,
  175. return inf;
  176. }
  177. - name = grub_malloc (grub_strlen (card->name)
  178. - + GRUB_NET_MAX_STR_HWADDR_LEN
  179. - + sizeof (":link"));
  180. + if (grub_add (grub_strlen (card->name),
  181. + (GRUB_NET_MAX_STR_HWADDR_LEN + sizeof (":link")), &sz))
  182. + {
  183. + grub_error (GRUB_ERR_OUT_OF_RANGE,
  184. + "overflow detected while obtaining size of link name");
  185. + return NULL;
  186. + }
  187. + name = grub_malloc (sz);
  188. if (!name)
  189. return NULL;
  190. @@ -1435,9 +1450,15 @@ grub_net_open_real (const char *name)
  191. if (grub_strchr (port_start + 1, ':'))
  192. {
  193. int iplen = grub_strlen (server);
  194. + grub_size_t sz;
  195. /* Bracket bare IPv6 addr. */
  196. - host = grub_malloc (iplen + 3);
  197. + if (grub_add (iplen, 3, &sz))
  198. + {
  199. + grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow detected while obtaining length of host"));
  200. + return NULL;
  201. + }
  202. + host = grub_malloc (sz);
  203. if (!host)
  204. return NULL;
  205. @@ -1692,6 +1713,7 @@ grub_env_set_net_property (const char *intername, const char *suffix,
  206. {
  207. char *varname, *varvalue;
  208. char *ptr;
  209. + grub_size_t sz;
  210. varname = grub_xasprintf ("net_%s_%s", intername, suffix);
  211. if (!varname)
  212. @@ -1699,7 +1721,12 @@ grub_env_set_net_property (const char *intername, const char *suffix,
  213. for (ptr = varname; *ptr; ptr++)
  214. if (*ptr == ':')
  215. *ptr = '_';
  216. - varvalue = grub_malloc (len + 1);
  217. + if (grub_add (len, 1, &sz))
  218. + {
  219. + grub_free (varname);
  220. + return grub_error (GRUB_ERR_OUT_OF_RANGE, "overflow detected while obtaining the size of an env variable");
  221. + }
  222. + varvalue = grub_malloc (sz);
  223. if (!varvalue)
  224. {
  225. grub_free (varname);
  226. --
  227. 2.50.1