File: fs-Prevent-overflows-when-assigning-returned-values-from-.patch

package info (click to toggle)
grub2 2.12-9
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 70,780 kB
  • sloc: ansic: 424,740; asm: 16,228; sh: 9,525; cpp: 2,095; makefile: 1,590; python: 1,468; sed: 431; lex: 393; yacc: 268; awk: 85; lisp: 54; perl: 31
file content (104 lines) | stat: -rw-r--r-- 4,113 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
From: Lidong Chen <lidong.chen@oracle.com>
Date: Tue, 21 Jan 2025 19:02:38 +0000
Subject: fs: Prevent overflows when assigning returned values from
 read_number()

The direct assignment of the unsigned long long value returned by
read_number() can potentially lead to an overflow on a 32-bit systems.
The fix replaces the direct assignments with calls to grub_cast()
which detects the overflows and safely assigns the values if no
overflow is detected.

Signed-off-by: Lidong Chen <lidong.chen@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
 grub-core/fs/cpio_common.c | 18 ++++++++++++++----
 grub-core/fs/tar.c         | 23 ++++++++++++++++-------
 2 files changed, 30 insertions(+), 11 deletions(-)

diff --git a/grub-core/fs/cpio_common.c b/grub-core/fs/cpio_common.c
index 6ba58b3..45ac119 100644
--- a/grub-core/fs/cpio_common.c
+++ b/grub-core/fs/cpio_common.c
@@ -62,11 +62,21 @@ grub_cpio_find_file (struct grub_archelp_data *data, char **name,
 #endif
       )
     return grub_error (GRUB_ERR_BAD_FS, "invalid cpio archive");
-  data->size = read_number (hd.filesize, ARRAY_SIZE (hd.filesize));
+
+  if (grub_cast (read_number (hd.filesize, ARRAY_SIZE (hd.filesize)), &data->size))
+    return grub_error (GRUB_ERR_BAD_FS, N_("data size overflow"));
+
   if (mtime)
-    *mtime = read_number (hd.mtime, ARRAY_SIZE (hd.mtime));
-  modeval = read_number (hd.mode, ARRAY_SIZE (hd.mode));
-  namesize = read_number (hd.namesize, ARRAY_SIZE (hd.namesize));
+    {
+      if (grub_cast (read_number (hd.mtime, ARRAY_SIZE (hd.mtime)), mtime))
+	return grub_error (GRUB_ERR_BAD_FS, N_("mtime overflow"));
+    }
+
+  if (grub_cast (read_number (hd.mode, ARRAY_SIZE (hd.mode)), &modeval))
+    return grub_error (GRUB_ERR_BAD_FS, N_("mode overflow"));
+
+  if (grub_cast (read_number (hd.namesize, ARRAY_SIZE (hd.namesize)), &namesize))
+    return grub_error (GRUB_ERR_BAD_FS, N_("namesize overflow"));
 
   /* Don't allow negative numbers.  */
   if (namesize >= 0x80000000)
diff --git a/grub-core/fs/tar.c b/grub-core/fs/tar.c
index fd2ec1f..1eaa534 100644
--- a/grub-core/fs/tar.c
+++ b/grub-core/fs/tar.c
@@ -99,9 +99,10 @@ grub_cpio_find_file (struct grub_archelp_data *data, char **name,
       if (hd.typeflag == 'L')
 	{
 	  grub_err_t err;
-	  grub_size_t namesize = read_number (hd.size, sizeof (hd.size));
+	  grub_size_t namesize;
 
-	  if (grub_add (namesize, 1, &sz))
+	  if (grub_cast (read_number (hd.size, sizeof (hd.size)), &namesize) ||
+	      grub_add (namesize, 1, &sz))
 	    return grub_error (GRUB_ERR_BAD_FS, N_("name size overflow"));
 
 	  *name = grub_malloc (sz);
@@ -123,9 +124,10 @@ grub_cpio_find_file (struct grub_archelp_data *data, char **name,
       if (hd.typeflag == 'K')
 	{
 	  grub_err_t err;
-	  grub_size_t linksize = read_number (hd.size, sizeof (hd.size));
+	  grub_size_t linksize;
 
-	  if (grub_add (linksize, 1, &sz))
+	  if (grub_cast (read_number (hd.size, sizeof (hd.size)), &linksize) ||
+	      grub_add (linksize, 1, &sz))
 	    return grub_error (GRUB_ERR_BAD_FS, N_("link size overflow"));
 
 	  if (data->linkname_alloc < sz)
@@ -174,15 +176,22 @@ grub_cpio_find_file (struct grub_archelp_data *data, char **name,
 	  (*name)[extra_size + sizeof (hd.name)] = 0;
 	}
 
-      data->size = read_number (hd.size, sizeof (hd.size));
+      if (grub_cast (read_number (hd.size, sizeof (hd.size)), &data->size))
+	return grub_error (GRUB_ERR_BAD_FS, N_("data size overflow"));
+
       data->dofs = data->hofs + GRUB_DISK_SECTOR_SIZE;
       data->next_hofs = data->dofs + ((data->size + GRUB_DISK_SECTOR_SIZE - 1) &
 			   ~(GRUB_DISK_SECTOR_SIZE - 1));
       if (mtime)
-	*mtime = read_number (hd.mtime, sizeof (hd.mtime));
+	{
+	  if (grub_cast (read_number (hd.mtime, sizeof (hd.mtime)), mtime))
+	    return grub_error (GRUB_ERR_BAD_FS, N_("mtime overflow"));
+	}
       if (mode)
 	{
-	  *mode = read_number (hd.mode, sizeof (hd.mode));
+	  if (grub_cast (read_number (hd.mode, sizeof (hd.mode)), mode))
+	    return grub_error (GRUB_ERR_BAD_FS, N_("mode overflow"));
+
 	  switch (hd.typeflag)
 	    {
 	      /* Hardlink.  */