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:
authorYongxin Liu <yongxin.liu@windriver.com>2020-11-04 08:43:33 +0800
committerRichard Purdie <richard.purdie@linuxfoundation.org>2020-11-08 14:03:21 +0000
commitbf0e7912c8a76eaeac12a4e1f523da8a10a8780d (patch)
treee3fe2039d9da6f69f70f2b2fb49d06be8eb8f53e /meta/recipes-bsp/grub/files/CVE-2020-15707-linux-Fix-integer-overflows-in-initrd-size-handling.patch
parent81a925ac9e21af3dee8cc4f6e548dca2b29c2e88 (diff)
downloadpoky-bf0e7912c8a76eaeac12a4e1f523da8a10a8780d.tar.gz
grub: clean up CVE patches
Clean up several patches introduced in commit 6732918498 ("grub:fix several CVEs in grub 2.04"). 1) Add CVE tags to individual patches. 2) Rename upstream patches and prefix them with CVE tags. 3) Add description of reference to upstream patch. (From OE-Core rev: bcb8b6719beaf6625e6b703e91958fe8afba5819) Signed-off-by: Yongxin Liu <yongxin.liu@windriver.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
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, 177 insertions, 0 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
new file mode 100644
index 0000000000..d4f9300c0a
--- /dev/null
+++ b/meta/recipes-bsp/grub/files/CVE-2020-15707-linux-Fix-integer-overflows-in-initrd-size-handling.patch
@@ -0,0 +1,177 @@
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