summaryrefslogtreecommitdiffstats
path: root/meta/recipes-bsp/grub/files/CVE-2020-15707-linux-Fix-integer-overflows-in-initrd-size-handling.patch
diff options
context:
space:
mode:
Diffstat (limited to 'meta/recipes-bsp/grub/files/CVE-2020-15707-linux-Fix-integer-overflows-in-initrd-size-handling.patch')
-rw-r--r--meta/recipes-bsp/grub/files/CVE-2020-15707-linux-Fix-integer-overflows-in-initrd-size-handling.patch177
1 files changed, 0 insertions, 177 deletions
diff --git a/meta/recipes-bsp/grub/files/CVE-2020-15707-linux-Fix-integer-overflows-in-initrd-size-handling.patch b/meta/recipes-bsp/grub/files/CVE-2020-15707-linux-Fix-integer-overflows-in-initrd-size-handling.patch
deleted file mode 100644
index d4f9300c0a..0000000000
--- a/meta/recipes-bsp/grub/files/CVE-2020-15707-linux-Fix-integer-overflows-in-initrd-size-handling.patch
+++ /dev/null
@@ -1,177 +0,0 @@
1From 68a09a74f6d726d79709847f3671c0a08e4fb5a0 Mon Sep 17 00:00:00 2001
2From: Colin Watson <cjwatson@debian.org>
3Date: Sat, 25 Jul 2020 12:15:37 +0100
4Subject: [PATCH 9/9] linux: Fix integer overflows in initrd size handling
5
6These could be triggered by a crafted filesystem with very large files.
7
8Fixes: CVE-2020-15707
9
10Signed-off-by: Colin Watson <cjwatson@debian.org>
11Reviewed-by: Jan Setje-Eilers <jan.setjeeilers@oracle.com>
12Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
13
14Upstream-Status: Backport
15CVE: CVE-2020-15707
16
17Reference to upstream patch:
18https://git.savannah.gnu.org/cgit/grub.git/commit/?id=e7b8856f8be3292afdb38d2e8c70ad8d62a61e10
19
20Signed-off-by: Yongxin Liu <yongxin.liu@windriver.com>
21---
22 grub-core/loader/linux.c | 74 +++++++++++++++++++++++++++++++++++-------------
23 1 file changed, 54 insertions(+), 20 deletions(-)
24
25diff --git a/grub-core/loader/linux.c b/grub-core/loader/linux.c
26index 471b214..8c8565a 100644
27--- a/grub-core/loader/linux.c
28+++ b/grub-core/loader/linux.c
29@@ -4,6 +4,7 @@
30 #include <grub/misc.h>
31 #include <grub/file.h>
32 #include <grub/mm.h>
33+#include <grub/safemath.h>
34
35 struct newc_head
36 {
37@@ -98,13 +99,13 @@ free_dir (struct dir *root)
38 grub_free (root);
39 }
40
41-static grub_size_t
42+static grub_err_t
43 insert_dir (const char *name, struct dir **root,
44- grub_uint8_t *ptr)
45+ grub_uint8_t *ptr, grub_size_t *size)
46 {
47 struct dir *cur, **head = root;
48 const char *cb, *ce = name;
49- grub_size_t size = 0;
50+ *size = 0;
51 while (1)
52 {
53 for (cb = ce; *cb == '/'; cb++);
54@@ -130,14 +131,22 @@ insert_dir (const char *name, struct dir **root,
55 ptr = make_header (ptr, name, ce - name,
56 040777, 0);
57 }
58- size += ALIGN_UP ((ce - (char *) name)
59- + sizeof (struct newc_head), 4);
60+ if (grub_add (*size,
61+ ALIGN_UP ((ce - (char *) name)
62+ + sizeof (struct newc_head), 4),
63+ size))
64+ {
65+ grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
66+ grub_free (n->name);
67+ grub_free (n);
68+ return grub_errno;
69+ }
70 *head = n;
71 cur = n;
72 }
73 root = &cur->next;
74 }
75- return size;
76+ return GRUB_ERR_NONE;
77 }
78
79 grub_err_t
80@@ -173,26 +182,33 @@ grub_initrd_init (int argc, char *argv[],
81 eptr = grub_strchr (ptr, ':');
82 if (eptr)
83 {
84+ grub_size_t dir_size, name_len;
85+
86 initrd_ctx->components[i].newc_name = grub_strndup (ptr, eptr - ptr);
87- if (!initrd_ctx->components[i].newc_name)
88+ if (!initrd_ctx->components[i].newc_name ||
89+ insert_dir (initrd_ctx->components[i].newc_name, &root, 0,
90+ &dir_size))
91 {
92 grub_initrd_close (initrd_ctx);
93 return grub_errno;
94 }
95- initrd_ctx->size
96- += ALIGN_UP (sizeof (struct newc_head)
97- + grub_strlen (initrd_ctx->components[i].newc_name),
98- 4);
99- initrd_ctx->size += insert_dir (initrd_ctx->components[i].newc_name,
100- &root, 0);
101+ name_len = grub_strlen (initrd_ctx->components[i].newc_name);
102+ if (grub_add (initrd_ctx->size,
103+ ALIGN_UP (sizeof (struct newc_head) + name_len, 4),
104+ &initrd_ctx->size) ||
105+ grub_add (initrd_ctx->size, dir_size, &initrd_ctx->size))
106+ goto overflow;
107 newc = 1;
108 fname = eptr + 1;
109 }
110 }
111 else if (newc)
112 {
113- initrd_ctx->size += ALIGN_UP (sizeof (struct newc_head)
114- + sizeof ("TRAILER!!!") - 1, 4);
115+ if (grub_add (initrd_ctx->size,
116+ ALIGN_UP (sizeof (struct newc_head)
117+ + sizeof ("TRAILER!!!") - 1, 4),
118+ &initrd_ctx->size))
119+ goto overflow;
120 free_dir (root);
121 root = 0;
122 newc = 0;
123@@ -208,19 +224,29 @@ grub_initrd_init (int argc, char *argv[],
124 initrd_ctx->nfiles++;
125 initrd_ctx->components[i].size
126 = grub_file_size (initrd_ctx->components[i].file);
127- initrd_ctx->size += initrd_ctx->components[i].size;
128+ if (grub_add (initrd_ctx->size, initrd_ctx->components[i].size,
129+ &initrd_ctx->size))
130+ goto overflow;
131 }
132
133 if (newc)
134 {
135 initrd_ctx->size = ALIGN_UP (initrd_ctx->size, 4);
136- initrd_ctx->size += ALIGN_UP (sizeof (struct newc_head)
137- + sizeof ("TRAILER!!!") - 1, 4);
138+ if (grub_add (initrd_ctx->size,
139+ ALIGN_UP (sizeof (struct newc_head)
140+ + sizeof ("TRAILER!!!") - 1, 4),
141+ &initrd_ctx->size))
142+ goto overflow;
143 free_dir (root);
144 root = 0;
145 }
146
147 return GRUB_ERR_NONE;
148+
149+ overflow:
150+ free_dir (root);
151+ grub_initrd_close (initrd_ctx);
152+ return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected"));
153 }
154
155 grub_size_t
156@@ -261,8 +287,16 @@ grub_initrd_load (struct grub_linux_initrd_context *initrd_ctx,
157
158 if (initrd_ctx->components[i].newc_name)
159 {
160- ptr += insert_dir (initrd_ctx->components[i].newc_name,
161- &root, ptr);
162+ grub_size_t dir_size;
163+
164+ if (insert_dir (initrd_ctx->components[i].newc_name, &root, ptr,
165+ &dir_size))
166+ {
167+ free_dir (root);
168+ grub_initrd_close (initrd_ctx);
169+ return grub_errno;
170+ }
171+ ptr += dir_size;
172 ptr = make_header (ptr, initrd_ctx->components[i].newc_name,
173 grub_strlen (initrd_ctx->components[i].newc_name),
174 0100777,
175--
1762.14.4
177