0049-fs-Use-safe-math-macros-to-prevent-overflows.patch 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  1. From 005280a4b3ba41ab0b4fea5e1d2a874646e6e12d Mon Sep 17 00:00:00 2001
  2. From: Lidong Chen <lidong.chen@oracle.com>
  3. Date: Tue, 21 Jan 2025 19:02:36 +0000
  4. Subject: [PATCH] fs: 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. Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
  9. Conflicts:
  10. grub-core/fs/erofs.c
  11. Upstream: 6608163b08a7a8be4b0ab2a5cd4593bba07fe2b7
  12. Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
  13. ---
  14. grub-core/fs/archelp.c | 9 ++++++++-
  15. grub-core/fs/btrfs.c | 34 ++++++++++++++++++++++++++++------
  16. grub-core/fs/cpio_common.c | 16 ++++++++++++++--
  17. grub-core/fs/f2fs.c | 17 +++++++++++++++--
  18. grub-core/fs/ntfscomp.c | 9 ++++++++-
  19. grub-core/fs/squash4.c | 12 +++++++++---
  20. grub-core/fs/xfs.c | 17 +++++++++++++++--
  21. 7 files changed, 97 insertions(+), 17 deletions(-)
  22. diff --git a/grub-core/fs/archelp.c b/grub-core/fs/archelp.c
  23. index c1dcc6285..0816b28de 100644
  24. --- a/grub-core/fs/archelp.c
  25. +++ b/grub-core/fs/archelp.c
  26. @@ -21,6 +21,7 @@
  27. #include <grub/fs.h>
  28. #include <grub/disk.h>
  29. #include <grub/dl.h>
  30. +#include <grub/safemath.h>
  31. GRUB_MOD_LICENSE ("GPLv3+");
  32. @@ -68,6 +69,7 @@ handle_symlink (struct grub_archelp_data *data,
  33. char *rest;
  34. char *linktarget;
  35. grub_size_t linktarget_len;
  36. + grub_size_t sz;
  37. *restart = 0;
  38. @@ -98,7 +100,12 @@ handle_symlink (struct grub_archelp_data *data,
  39. if (linktarget[0] == '\0')
  40. return GRUB_ERR_NONE;
  41. linktarget_len = grub_strlen (linktarget);
  42. - target = grub_malloc (linktarget_len + grub_strlen (*name) + 2);
  43. +
  44. + if (grub_add (linktarget_len, grub_strlen (*name), &sz) ||
  45. + grub_add (sz, 2, &sz))
  46. + return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("link target length overflow"));
  47. +
  48. + target = grub_malloc (sz);
  49. if (!target)
  50. return grub_errno;
  51. diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c
  52. index aae81482b..0625b1166 100644
  53. --- a/grub-core/fs/btrfs.c
  54. +++ b/grub-core/fs/btrfs.c
  55. @@ -1801,6 +1801,7 @@ find_path (struct grub_btrfs_data *data,
  56. char *path_alloc = NULL;
  57. char *origpath = NULL;
  58. unsigned symlinks_max = 32;
  59. + grub_size_t sz;
  60. err = get_root (data, key, tree, type);
  61. if (err)
  62. @@ -1891,9 +1892,15 @@ find_path (struct grub_btrfs_data *data,
  63. struct grub_btrfs_dir_item *cdirel;
  64. if (elemsize > allocated)
  65. {
  66. - allocated = 2 * elemsize;
  67. + if (grub_mul (2, elemsize, &allocated) ||
  68. + grub_add (allocated, 1, &sz))
  69. + {
  70. + grub_free (path_alloc);
  71. + grub_free (origpath);
  72. + return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("directory item size overflow"));
  73. + }
  74. grub_free (direl);
  75. - direl = grub_malloc (allocated + 1);
  76. + direl = grub_malloc (sz);
  77. if (!direl)
  78. {
  79. grub_free (path_alloc);
  80. @@ -1955,8 +1962,16 @@ find_path (struct grub_btrfs_data *data,
  81. grub_free (origpath);
  82. return err;
  83. }
  84. - tmp = grub_malloc (grub_le_to_cpu64 (inode.size)
  85. - + grub_strlen (path) + 1);
  86. +
  87. + if (grub_add (grub_le_to_cpu64 (inode.size), grub_strlen (path), &sz) ||
  88. + grub_add (sz, 1, &sz))
  89. + {
  90. + grub_free (direl);
  91. + grub_free (path_alloc);
  92. + grub_free (origpath);
  93. + return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("buffer size overflow"));
  94. + }
  95. + tmp = grub_malloc (sz);
  96. if (!tmp)
  97. {
  98. grub_free (direl);
  99. @@ -2078,6 +2093,7 @@ grub_btrfs_dir (grub_device_t device, const char *path,
  100. grub_uint64_t tree;
  101. grub_uint8_t type;
  102. grub_size_t est_size = 0;
  103. + grub_size_t sz;
  104. if (!data)
  105. return grub_errno;
  106. @@ -2119,9 +2135,15 @@ grub_btrfs_dir (grub_device_t device, const char *path,
  107. }
  108. if (elemsize > allocated)
  109. {
  110. - allocated = 2 * elemsize;
  111. + if (grub_mul (2, elemsize, &allocated) ||
  112. + grub_add (allocated, 1, &sz))
  113. + {
  114. + grub_error (GRUB_ERR_OUT_OF_RANGE, N_("directory element size overflow"));
  115. + r = -grub_errno;
  116. + break;
  117. + }
  118. grub_free (direl);
  119. - direl = grub_malloc (allocated + 1);
  120. + direl = grub_malloc (sz);
  121. if (!direl)
  122. {
  123. r = -grub_errno;
  124. diff --git a/grub-core/fs/cpio_common.c b/grub-core/fs/cpio_common.c
  125. index 5d41b6fdb..6ba58b354 100644
  126. --- a/grub-core/fs/cpio_common.c
  127. +++ b/grub-core/fs/cpio_common.c
  128. @@ -24,6 +24,7 @@
  129. #include <grub/dl.h>
  130. #include <grub/i18n.h>
  131. #include <grub/archelp.h>
  132. +#include <grub/safemath.h>
  133. GRUB_MOD_LICENSE ("GPLv3+");
  134. @@ -48,6 +49,7 @@ grub_cpio_find_file (struct grub_archelp_data *data, char **name,
  135. struct head hd;
  136. grub_size_t namesize;
  137. grub_uint32_t modeval;
  138. + grub_size_t sz;
  139. data->hofs = data->next_hofs;
  140. @@ -76,7 +78,10 @@ grub_cpio_find_file (struct grub_archelp_data *data, char **name,
  141. *mode = modeval;
  142. - *name = grub_malloc (namesize + 1);
  143. + if (grub_add (namesize, 1, &sz))
  144. + return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("file name size overflow"));
  145. +
  146. + *name = grub_malloc (sz);
  147. if (*name == NULL)
  148. return grub_errno;
  149. @@ -110,10 +115,17 @@ grub_cpio_get_link_target (struct grub_archelp_data *data)
  150. {
  151. char *ret;
  152. grub_err_t err;
  153. + grub_size_t sz;
  154. if (data->size == 0)
  155. return grub_strdup ("");
  156. - ret = grub_malloc (data->size + 1);
  157. +
  158. + if (grub_add (data->size, 1, &sz))
  159. + {
  160. + grub_error (GRUB_ERR_OUT_OF_RANGE, N_("target data size overflow"));
  161. + return NULL;
  162. + }
  163. + ret = grub_malloc (sz);
  164. if (!ret)
  165. return NULL;
  166. diff --git a/grub-core/fs/f2fs.c b/grub-core/fs/f2fs.c
  167. index f6d6beaa5..72b4aa1e6 100644
  168. --- a/grub-core/fs/f2fs.c
  169. +++ b/grub-core/fs/f2fs.c
  170. @@ -28,6 +28,7 @@
  171. #include <grub/types.h>
  172. #include <grub/charset.h>
  173. #include <grub/fshelp.h>
  174. +#include <grub/safemath.h>
  175. GRUB_MOD_LICENSE ("GPLv3+");
  176. @@ -958,6 +959,7 @@ grub_f2fs_read_symlink (grub_fshelp_node_t node)
  177. char *symlink;
  178. struct grub_fshelp_node *diro = node;
  179. grub_uint64_t filesize;
  180. + grub_size_t sz;
  181. if (!diro->inode_read)
  182. {
  183. @@ -968,7 +970,12 @@ grub_f2fs_read_symlink (grub_fshelp_node_t node)
  184. filesize = grub_f2fs_file_size(&diro->inode.i);
  185. - symlink = grub_malloc (filesize + 1);
  186. + if (grub_add (filesize, 1, &sz))
  187. + {
  188. + grub_error (GRUB_ERR_OUT_OF_RANGE, N_("symlink size overflow"));
  189. + return 0;
  190. + }
  191. + symlink = grub_malloc (sz);
  192. if (!symlink)
  193. return 0;
  194. @@ -997,6 +1004,7 @@ grub_f2fs_check_dentries (struct grub_f2fs_dir_iter_ctx *ctx)
  195. enum FILE_TYPE ftype;
  196. int name_len;
  197. int ret;
  198. + int sz;
  199. if (grub_f2fs_test_bit_le (i, ctx->bitmap) == 0)
  200. {
  201. @@ -1010,7 +1018,12 @@ grub_f2fs_check_dentries (struct grub_f2fs_dir_iter_ctx *ctx)
  202. if (name_len >= F2FS_NAME_LEN)
  203. return 0;
  204. - filename = grub_malloc (name_len + 1);
  205. + if (grub_add (name_len, 1, &sz))
  206. + {
  207. + grub_error (GRUB_ERR_OUT_OF_RANGE, N_("directory entry name length overflow"));
  208. + return 0;
  209. + }
  210. + filename = grub_malloc (sz);
  211. if (!filename)
  212. return 0;
  213. diff --git a/grub-core/fs/ntfscomp.c b/grub-core/fs/ntfscomp.c
  214. index a009f2c2d..f168a318e 100644
  215. --- a/grub-core/fs/ntfscomp.c
  216. +++ b/grub-core/fs/ntfscomp.c
  217. @@ -22,6 +22,7 @@
  218. #include <grub/disk.h>
  219. #include <grub/dl.h>
  220. #include <grub/ntfs.h>
  221. +#include <grub/safemath.h>
  222. GRUB_MOD_LICENSE ("GPLv3+");
  223. @@ -310,6 +311,7 @@ ntfscomp (grub_uint8_t *dest, grub_disk_addr_t ofs,
  224. {
  225. grub_err_t ret;
  226. grub_disk_addr_t vcn;
  227. + int log_sz;
  228. if (ctx->attr->sbuf)
  229. {
  230. @@ -349,7 +351,12 @@ ntfscomp (grub_uint8_t *dest, grub_disk_addr_t ofs,
  231. }
  232. ctx->comp.comp_head = ctx->comp.comp_tail = 0;
  233. - ctx->comp.cbuf = grub_malloc (1 << (ctx->comp.log_spc + GRUB_NTFS_BLK_SHR));
  234. + if (grub_add (ctx->comp.log_spc, GRUB_NTFS_BLK_SHR, &log_sz))
  235. + {
  236. + grub_error (GRUB_ERR_OUT_OF_RANGE, N_("compression buffer size overflow"));
  237. + return 0;
  238. + }
  239. + ctx->comp.cbuf = grub_malloc (1 << log_sz);
  240. if (!ctx->comp.cbuf)
  241. return 0;
  242. diff --git a/grub-core/fs/squash4.c b/grub-core/fs/squash4.c
  243. index 6e9d63874..f91ff3bfa 100644
  244. --- a/grub-core/fs/squash4.c
  245. +++ b/grub-core/fs/squash4.c
  246. @@ -460,11 +460,11 @@ grub_squash_read_symlink (grub_fshelp_node_t node)
  247. {
  248. char *ret;
  249. grub_err_t err;
  250. - grub_size_t sz;
  251. + grub_uint32_t sz;
  252. if (grub_add (grub_le_to_cpu32 (node->ino.symlink.namelen), 1, &sz))
  253. {
  254. - grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
  255. + grub_error (GRUB_ERR_OUT_OF_RANGE, N_("symlink name length overflow"));
  256. return NULL;
  257. }
  258. @@ -580,6 +580,7 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir,
  259. struct grub_squash_dirent di;
  260. struct grub_squash_inode ino;
  261. grub_size_t sz;
  262. + grub_uint16_t nlen;
  263. err = read_chunk (dir->data, &di, sizeof (di),
  264. grub_le_to_cpu64 (dir->data->sb.diroffset)
  265. @@ -595,7 +596,12 @@ grub_squash_iterate_dir (grub_fshelp_node_t dir,
  266. if (err)
  267. return 0;
  268. - buf = grub_malloc (grub_le_to_cpu16 (di.namelen) + 2);
  269. + if (grub_add (grub_le_to_cpu16 (di.namelen), 2, &nlen))
  270. + {
  271. + grub_error (GRUB_ERR_OUT_OF_RANGE, N_("name length overflow"));
  272. + return 0;
  273. + }
  274. + buf = grub_malloc (nlen);
  275. if (!buf)
  276. return 0;
  277. err = read_chunk (dir->data, buf,
  278. diff --git a/grub-core/fs/xfs.c b/grub-core/fs/xfs.c
  279. index 74feeb86a..70c9f449b 100644
  280. --- a/grub-core/fs/xfs.c
  281. +++ b/grub-core/fs/xfs.c
  282. @@ -718,6 +718,7 @@ static char *
  283. grub_xfs_read_symlink (grub_fshelp_node_t node)
  284. {
  285. grub_ssize_t size = grub_be_to_cpu64 (node->inode.size);
  286. + grub_size_t sz;
  287. if (size < 0)
  288. {
  289. @@ -739,7 +740,12 @@ grub_xfs_read_symlink (grub_fshelp_node_t node)
  290. if (node->data->hascrc)
  291. off = 56;
  292. - symlink = grub_malloc (size + 1);
  293. + if (grub_add (size, 1, &sz))
  294. + {
  295. + grub_error (GRUB_ERR_OUT_OF_RANGE, N_("symlink size overflow"));
  296. + return 0;
  297. + }
  298. + symlink = grub_malloc (sz);
  299. if (!symlink)
  300. return 0;
  301. @@ -789,8 +795,15 @@ static int iterate_dir_call_hook (grub_uint64_t ino, const char *filename,
  302. {
  303. struct grub_fshelp_node *fdiro;
  304. grub_err_t err;
  305. + grub_size_t sz;
  306. - fdiro = grub_malloc (grub_xfs_fshelp_size(ctx->diro->data) + 1);
  307. + if (grub_add (grub_xfs_fshelp_size(ctx->diro->data), 1, &sz))
  308. + {
  309. + grub_error (GRUB_ERR_OUT_OF_RANGE, N_("directory data size overflow"));
  310. + grub_print_error ();
  311. + return 0;
  312. + }
  313. + fdiro = grub_malloc (sz);
  314. if (!fdiro)
  315. {
  316. grub_print_error ();
  317. --
  318. 2.50.1