diff options
author | Yongxin Liu <yongxin.liu@windriver.com> | 2020-10-28 11:18:06 +0800 |
---|---|---|
committer | Richard Purdie <richard.purdie@linuxfoundation.org> | 2020-11-12 13:07:52 +0000 |
commit | 5b716fa8e2562a1f942c2d920a3f727c3841c4f3 (patch) | |
tree | 2f9803068abf3f4ef9d3a3109f382788b4bf4ce1 /meta/recipes-bsp/grub/files/0008-linux-Fix-integer-overflows-in-initrd-size-handling.patch | |
parent | 59c65998c8e87758aec4ad77e96cf212f0b47f40 (diff) | |
download | poky-5b716fa8e2562a1f942c2d920a3f727c3841c4f3.tar.gz |
grub: fix several CVEs in grub 2.04
Backport patches from https://git.savannah.gnu.org/git/grub.git
to fix some CVEs. Here is the list.
CVE-2020-14308:
0001-calloc-Make-sure-we-always-have-an-overflow-checking.patch
0002-lvm-Add-LVM-cache-logical-volume-handling.patch
0003-calloc-Use-calloc-at-most-places.patch
CVE-2020-14309, CVE-2020-14310, CVE-2020-14311:
0004-safemath-Add-some-arithmetic-primitives-that-check-f.patch
0005-malloc-Use-overflow-checking-primitives-where-we-do-.patch
CVE-2020-15706:
0006-script-Remove-unused-fields-from-grub_script_functio.patch
0007-script-Avoid-a-use-after-free-when-redefining-a-func.patch
CVE-2020-15707:
0008-linux-Fix-integer-overflows-in-initrd-size-handling.patch
(From OE-Core rev: af52a1f1f3a2ab61fea263c3dd17628f359ec906)
Signed-off-by: Yongxin Liu <yongxin.liu@windriver.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
(cherry picked from commit 67329184985a03534f11f95e9df5f9fb2305a261)
Signed-off-by: Steve Sakoman <steve@sakoman.com>
Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta/recipes-bsp/grub/files/0008-linux-Fix-integer-overflows-in-initrd-size-handling.patch')
-rw-r--r-- | meta/recipes-bsp/grub/files/0008-linux-Fix-integer-overflows-in-initrd-size-handling.patch | 173 |
1 files changed, 173 insertions, 0 deletions
diff --git a/meta/recipes-bsp/grub/files/0008-linux-Fix-integer-overflows-in-initrd-size-handling.patch b/meta/recipes-bsp/grub/files/0008-linux-Fix-integer-overflows-in-initrd-size-handling.patch new file mode 100644 index 0000000000..0731f0ec53 --- /dev/null +++ b/meta/recipes-bsp/grub/files/0008-linux-Fix-integer-overflows-in-initrd-size-handling.patch | |||
@@ -0,0 +1,173 @@ | |||
1 | From 68a09a74f6d726d79709847f3671c0a08e4fb5a0 Mon Sep 17 00:00:00 2001 | ||
2 | From: Colin Watson <cjwatson@debian.org> | ||
3 | Date: Sat, 25 Jul 2020 12:15:37 +0100 | ||
4 | Subject: [PATCH 9/9] linux: Fix integer overflows in initrd size handling | ||
5 | |||
6 | These could be triggered by a crafted filesystem with very large files. | ||
7 | |||
8 | Fixes: CVE-2020-15707 | ||
9 | |||
10 | Upstream-Status: Backport [commit e7b8856f8be3292afdb38d2e8c70ad8d62a61e10 | ||
11 | from https://git.savannah.gnu.org/git/grub.git] | ||
12 | |||
13 | Signed-off-by: Colin Watson <cjwatson@debian.org> | ||
14 | Reviewed-by: Jan Setje-Eilers <jan.setjeeilers@oracle.com> | ||
15 | Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com> | ||
16 | Signed-off-by: Yongxin Liu <yongxin.liu@windriver.com> | ||
17 | --- | ||
18 | grub-core/loader/linux.c | 74 +++++++++++++++++++++++++++++++++++------------- | ||
19 | 1 file changed, 54 insertions(+), 20 deletions(-) | ||
20 | |||
21 | diff --git a/grub-core/loader/linux.c b/grub-core/loader/linux.c | ||
22 | index 471b214..8c8565a 100644 | ||
23 | --- a/grub-core/loader/linux.c | ||
24 | +++ b/grub-core/loader/linux.c | ||
25 | @@ -4,6 +4,7 @@ | ||
26 | #include <grub/misc.h> | ||
27 | #include <grub/file.h> | ||
28 | #include <grub/mm.h> | ||
29 | +#include <grub/safemath.h> | ||
30 | |||
31 | struct newc_head | ||
32 | { | ||
33 | @@ -98,13 +99,13 @@ free_dir (struct dir *root) | ||
34 | grub_free (root); | ||
35 | } | ||
36 | |||
37 | -static grub_size_t | ||
38 | +static grub_err_t | ||
39 | insert_dir (const char *name, struct dir **root, | ||
40 | - grub_uint8_t *ptr) | ||
41 | + grub_uint8_t *ptr, grub_size_t *size) | ||
42 | { | ||
43 | struct dir *cur, **head = root; | ||
44 | const char *cb, *ce = name; | ||
45 | - grub_size_t size = 0; | ||
46 | + *size = 0; | ||
47 | while (1) | ||
48 | { | ||
49 | for (cb = ce; *cb == '/'; cb++); | ||
50 | @@ -130,14 +131,22 @@ insert_dir (const char *name, struct dir **root, | ||
51 | ptr = make_header (ptr, name, ce - name, | ||
52 | 040777, 0); | ||
53 | } | ||
54 | - size += ALIGN_UP ((ce - (char *) name) | ||
55 | - + sizeof (struct newc_head), 4); | ||
56 | + if (grub_add (*size, | ||
57 | + ALIGN_UP ((ce - (char *) name) | ||
58 | + + sizeof (struct newc_head), 4), | ||
59 | + size)) | ||
60 | + { | ||
61 | + grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); | ||
62 | + grub_free (n->name); | ||
63 | + grub_free (n); | ||
64 | + return grub_errno; | ||
65 | + } | ||
66 | *head = n; | ||
67 | cur = n; | ||
68 | } | ||
69 | root = &cur->next; | ||
70 | } | ||
71 | - return size; | ||
72 | + return GRUB_ERR_NONE; | ||
73 | } | ||
74 | |||
75 | grub_err_t | ||
76 | @@ -173,26 +182,33 @@ grub_initrd_init (int argc, char *argv[], | ||
77 | eptr = grub_strchr (ptr, ':'); | ||
78 | if (eptr) | ||
79 | { | ||
80 | + grub_size_t dir_size, name_len; | ||
81 | + | ||
82 | initrd_ctx->components[i].newc_name = grub_strndup (ptr, eptr - ptr); | ||
83 | - if (!initrd_ctx->components[i].newc_name) | ||
84 | + if (!initrd_ctx->components[i].newc_name || | ||
85 | + insert_dir (initrd_ctx->components[i].newc_name, &root, 0, | ||
86 | + &dir_size)) | ||
87 | { | ||
88 | grub_initrd_close (initrd_ctx); | ||
89 | return grub_errno; | ||
90 | } | ||
91 | - initrd_ctx->size | ||
92 | - += ALIGN_UP (sizeof (struct newc_head) | ||
93 | - + grub_strlen (initrd_ctx->components[i].newc_name), | ||
94 | - 4); | ||
95 | - initrd_ctx->size += insert_dir (initrd_ctx->components[i].newc_name, | ||
96 | - &root, 0); | ||
97 | + name_len = grub_strlen (initrd_ctx->components[i].newc_name); | ||
98 | + if (grub_add (initrd_ctx->size, | ||
99 | + ALIGN_UP (sizeof (struct newc_head) + name_len, 4), | ||
100 | + &initrd_ctx->size) || | ||
101 | + grub_add (initrd_ctx->size, dir_size, &initrd_ctx->size)) | ||
102 | + goto overflow; | ||
103 | newc = 1; | ||
104 | fname = eptr + 1; | ||
105 | } | ||
106 | } | ||
107 | else if (newc) | ||
108 | { | ||
109 | - initrd_ctx->size += ALIGN_UP (sizeof (struct newc_head) | ||
110 | - + sizeof ("TRAILER!!!") - 1, 4); | ||
111 | + if (grub_add (initrd_ctx->size, | ||
112 | + ALIGN_UP (sizeof (struct newc_head) | ||
113 | + + sizeof ("TRAILER!!!") - 1, 4), | ||
114 | + &initrd_ctx->size)) | ||
115 | + goto overflow; | ||
116 | free_dir (root); | ||
117 | root = 0; | ||
118 | newc = 0; | ||
119 | @@ -208,19 +224,29 @@ grub_initrd_init (int argc, char *argv[], | ||
120 | initrd_ctx->nfiles++; | ||
121 | initrd_ctx->components[i].size | ||
122 | = grub_file_size (initrd_ctx->components[i].file); | ||
123 | - initrd_ctx->size += initrd_ctx->components[i].size; | ||
124 | + if (grub_add (initrd_ctx->size, initrd_ctx->components[i].size, | ||
125 | + &initrd_ctx->size)) | ||
126 | + goto overflow; | ||
127 | } | ||
128 | |||
129 | if (newc) | ||
130 | { | ||
131 | initrd_ctx->size = ALIGN_UP (initrd_ctx->size, 4); | ||
132 | - initrd_ctx->size += ALIGN_UP (sizeof (struct newc_head) | ||
133 | - + sizeof ("TRAILER!!!") - 1, 4); | ||
134 | + if (grub_add (initrd_ctx->size, | ||
135 | + ALIGN_UP (sizeof (struct newc_head) | ||
136 | + + sizeof ("TRAILER!!!") - 1, 4), | ||
137 | + &initrd_ctx->size)) | ||
138 | + goto overflow; | ||
139 | free_dir (root); | ||
140 | root = 0; | ||
141 | } | ||
142 | |||
143 | return GRUB_ERR_NONE; | ||
144 | + | ||
145 | + overflow: | ||
146 | + free_dir (root); | ||
147 | + grub_initrd_close (initrd_ctx); | ||
148 | + return grub_error (GRUB_ERR_OUT_OF_RANGE, N_("overflow is detected")); | ||
149 | } | ||
150 | |||
151 | grub_size_t | ||
152 | @@ -261,8 +287,16 @@ grub_initrd_load (struct grub_linux_initrd_context *initrd_ctx, | ||
153 | |||
154 | if (initrd_ctx->components[i].newc_name) | ||
155 | { | ||
156 | - ptr += insert_dir (initrd_ctx->components[i].newc_name, | ||
157 | - &root, ptr); | ||
158 | + grub_size_t dir_size; | ||
159 | + | ||
160 | + if (insert_dir (initrd_ctx->components[i].newc_name, &root, ptr, | ||
161 | + &dir_size)) | ||
162 | + { | ||
163 | + free_dir (root); | ||
164 | + grub_initrd_close (initrd_ctx); | ||
165 | + return grub_errno; | ||
166 | + } | ||
167 | + ptr += dir_size; | ||
168 | ptr = make_header (ptr, initrd_ctx->components[i].newc_name, | ||
169 | grub_strlen (initrd_ctx->components[i].newc_name), | ||
170 | 0100777, | ||
171 | -- | ||
172 | 2.14.4 | ||
173 | |||