!77 backport the patches that upstream community released on March 2, 2021

From: @zhangqiumiao
Reviewed-by: @t_feng
Signed-off-by: @t_feng
This commit is contained in:
openeuler-ci-bot 2021-03-29 19:37:08 +08:00 committed by Gitee
commit e70bcb5ec8
74 changed files with 4804 additions and 274 deletions

View File

@ -0,0 +1,40 @@
From e0cd3c9d4dd8e2f796e32e9cc0061e2298e18ef2 Mon Sep 17 00:00:00 2001
From: Darren Kenny <darren.kenny@oracle.com>
Date: Thu, 3 Dec 2020 14:39:45 +0000
Subject: [PATCH] mmap: Fix memory leak when iterating over mapped memory
When returning from grub_mmap_iterate() the memory allocated to present
is not being released causing it to leak.
Fixes: CID 96655
Reference: http://git.savannah.gnu.org/cgit/grub.git/commit/?id=8cb2848f9699642a698af84b12ba187cab722031
Signed-off-by: Darren Kenny <darren.kenny@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/mmap/mmap.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/grub-core/mmap/mmap.c b/grub-core/mmap/mmap.c
index 3cae683..c8c8312 100644
--- a/grub-core/mmap/mmap.c
+++ b/grub-core/mmap/mmap.c
@@ -270,6 +270,7 @@ grub_mmap_iterate (grub_memory_hook_t hook, void *hook_data)
hook_data))
{
grub_free (ctx.scanline_events);
+ grub_free (present);
return GRUB_ERR_NONE;
}
@@ -282,6 +283,7 @@ grub_mmap_iterate (grub_memory_hook_t hook, void *hook_data)
}
grub_free (ctx.scanline_events);
+ grub_free (present);
return GRUB_ERR_NONE;
}
--
2.19.1

View File

@ -0,0 +1,38 @@
From 1600d11874762eab2235555e0171215cf9258da5 Mon Sep 17 00:00:00 2001
From: Darren Kenny <darren.kenny@oracle.com>
Date: Fri, 27 Nov 2020 15:10:26 +0000
Subject: [PATCH] net/net: Fix possible dereference to of a NULL pointer
It is always possible that grub_zalloc() could fail, so we should check for
a NULL return. Otherwise we run the risk of dereferencing a NULL pointer.
Fixes: CID 296221
Reference: http://git.savannah.gnu.org/cgit/grub.git/commit/?id=03f2515ae0c503406f1a99a2178405049c6555db
---
grub-core/net/net.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/grub-core/net/net.c b/grub-core/net/net.c
index ad024c9..d2fac17 100644
--- a/grub-core/net/net.c
+++ b/grub-core/net/net.c
@@ -89,8 +89,13 @@ grub_net_link_layer_add_address (struct grub_net_card *card,
/* Add sender to cache table. */
if (card->link_layer_table == NULL)
- card->link_layer_table = grub_zalloc (LINK_LAYER_CACHE_SIZE
- * sizeof (card->link_layer_table[0]));
+ {
+ card->link_layer_table = grub_zalloc (LINK_LAYER_CACHE_SIZE
+ * sizeof (card->link_layer_table[0]));
+ if (card->link_layer_table == NULL)
+ return;
+ }
+
entry = &(card->link_layer_table[card->new_ll_entry]);
entry->avail = 1;
grub_memcpy (&entry->ll_address, ll, sizeof (entry->ll_address));
--
2.19.1

View File

@ -0,0 +1,35 @@
From 7d02eb14ad9119643e9727b11efff13662fe9063 Mon Sep 17 00:00:00 2001
From: Darren Kenny <darren.kenny@oracle.com>
Date: Fri, 19 Feb 2021 17:12:23 +0000
Subject: [PATCH] net/tftp: Fix dangling memory pointer
The static code analysis tool, Parfait, reported that the valid of
file->data was left referencing memory that was freed by the call to
grub_free(data) where data was initialized from file->data.
To ensure that there is no unintentional access to this memory
referenced by file->data we should set the pointer to NULL.
Reference: http://git.savannah.gnu.org/cgit/grub.git/commit/grub-core/net/tftp.c?id=0cb838b281a68b536a09681f9557ea6a7ac5da7a
Signed-off-by: Darren Kenny <darren.kenny@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/net/tftp.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/grub-core/net/tftp.c b/grub-core/net/tftp.c
index c054072..658caa2 100644
--- a/grub-core/net/tftp.c
+++ b/grub-core/net/tftp.c
@@ -448,6 +448,7 @@ tftp_close (struct grub_file *file)
grub_net_udp_close (data->sock);
}
grub_free (data);
+ file->data = NULL;
return GRUB_ERR_NONE;
}
--
2.19.1

View File

@ -0,0 +1,31 @@
From b62f77df4d5582bf0999f92f3cf53cb6e3c100ec Mon Sep 17 00:00:00 2001
From: Darren Kenny <darren.kenny@oracle.com>
Date: Thu, 5 Nov 2020 10:15:25 +0000
Subject: [PATCH] kern/efi: Fix memory leak on failure
Free the memory allocated to name before returning on failure.
Fixes: CID 296222
Reference: http://git.savannah.gnu.org/cgit/grub.git/commit/?id=ed286ceba6015d37a9304f04602451c47bf195d7
Signed-off-by: Darren Kenny <darren.kenny@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/kern/efi/efi.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c
index c45c8f4..f3e24f9 100644
--- a/grub-core/kern/efi/efi.c
+++ b/grub-core/kern/efi/efi.c
@@ -406,6 +406,7 @@ grub_efi_get_filename (grub_efi_device_path_t *dp0)
{
grub_error (GRUB_ERR_OUT_OF_RANGE,
"malformed EFI Device Path node has length=%d", len);
+ grub_free (name);
return NULL;
}
--
2.19.1

View File

@ -0,0 +1,67 @@
From 17e7c7cd02d2cf14b16f9cb8aaad3d62c35b5609 Mon Sep 17 00:00:00 2001
From: Darren Kenny <darren.kenny@oracle.com>
Date: Fri, 11 Dec 2020 15:03:13 +0000
Subject: [PATCH] kern/efi/mm: Fix possible NULL pointer dereference
The model of grub_efi_get_memory_map() is that if memory_map is NULL,
then the purpose is to discover how much memory should be allocated to
it for the subsequent call.
The problem here is that with grub_efi_is_finished set to 1, there is no
check at all that the function is being called with a non-NULL memory_map.
While this MAY be true, we shouldn't assume it.
The solution to this is to behave as expected, and if memory_map is NULL,
then don't try to use it and allow memory_map_size to be filled in, and
return 0 as is done later in the code if the buffer is too small (or NULL).
Additionally, drop unneeded ret = 1.
Fixes: CID 96632
Reference: http://git.savannah.gnu.org/cgit/grub.git/commit/?id=6aee4bfd6973c714056fb7b56890b8d524e94ee1
Signed-off-by: Darren Kenny <darren.kenny@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/kern/efi/mm.c | 19 ++++++++++++++-----
1 file changed, 14 insertions(+), 5 deletions(-)
diff --git a/grub-core/kern/efi/mm.c b/grub-core/kern/efi/mm.c
index d70e5b4..f64f79e 100644
--- a/grub-core/kern/efi/mm.c
+++ b/grub-core/kern/efi/mm.c
@@ -375,15 +375,24 @@ grub_efi_get_memory_map (grub_efi_uintn_t *memory_map_size,
if (grub_efi_is_finished)
{
int ret = 1;
- if (*memory_map_size < finish_mmap_size)
+
+ if (memory_map != NULL)
{
- grub_memcpy (memory_map, finish_mmap_buf, *memory_map_size);
- ret = 0;
+ if (*memory_map_size < finish_mmap_size)
+ {
+ grub_memcpy (memory_map, finish_mmap_buf, *memory_map_size);
+ ret = 0;
+ }
+ else
+ grub_memcpy (memory_map, finish_mmap_buf, finish_mmap_size);
}
else
{
- grub_memcpy (memory_map, finish_mmap_buf, finish_mmap_size);
- ret = 1;
+ /*
+ * Incomplete, no buffer to copy into, same as
+ * GRUB_EFI_BUFFER_TOO_SMALL below.
+ */
+ ret = 0;
}
*memory_map_size = finish_mmap_size;
if (map_key)
--
2.19.1

View File

@ -0,0 +1,36 @@
From 4567a832aaade9589162e6f7a50af81af151d635 Mon Sep 17 00:00:00 2001
From: Darren Kenny <darren.kenny@oracle.com>
Date: Thu, 5 Nov 2020 10:29:59 +0000
Subject: [PATCH] zstd: Initialize seq_t structure fully
While many compilers will initialize this to zero, not all will, so it
is better to be sure that fields not being explicitly set are at known
values, and there is code that checks this fields value elsewhere in the
code.
Fixes: CID 292440
Reference: http://git.savannah.gnu.org/cgit/grub.git/commit/?id=2777cf4466719921dbe4b30af358a75e7d76f217
Signed-off-by: Darren Kenny <darren.kenny@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/lib/zstd/zstd_decompress.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/grub-core/lib/zstd/zstd_decompress.c b/grub-core/lib/zstd/zstd_decompress.c
index 711b5b6..e4b5670 100644
--- a/grub-core/lib/zstd/zstd_decompress.c
+++ b/grub-core/lib/zstd/zstd_decompress.c
@@ -1325,7 +1325,7 @@ typedef enum { ZSTD_lo_isRegularOffset, ZSTD_lo_isLongOffset=1 } ZSTD_longOffset
FORCE_INLINE_TEMPLATE seq_t
ZSTD_decodeSequence(seqState_t* seqState, const ZSTD_longOffset_e longOffsets)
{
- seq_t seq;
+ seq_t seq = {0};
U32 const llBits = seqState->stateLL.table[seqState->stateLL.state].nbAdditionalBits;
U32 const mlBits = seqState->stateML.table[seqState->stateML.state].nbAdditionalBits;
U32 const ofBits = seqState->stateOffb.table[seqState->stateOffb.state].nbAdditionalBits;
--
2.19.1

View File

@ -0,0 +1,45 @@
From 3b75201b76a8b728fc3680be92f7391f75096013 Mon Sep 17 00:00:00 2001
From: Darren Kenny <darren.kenny@oracle.com>
Date: Fri, 23 Oct 2020 09:49:59 +0000
Subject: [PATCH] kern/partition: Check for NULL before dereferencing input
string
There is the possibility that the value of str comes from an external
source and continuing to use it before ever checking its validity is
wrong. So, needs fixing.
Additionally, drop unneeded part initialization.
Fixes: CID 292444
Reference: http://git.savannah.gnu.org/cgit/grub.git/commit/?id=bc9c468a2ce84bc767234eec888b71f1bc744fff
Signed-off-by: Darren Kenny <darren.kenny@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/kern/partition.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/grub-core/kern/partition.c b/grub-core/kern/partition.c
index 2c401b8..3068c4d 100644
--- a/grub-core/kern/partition.c
+++ b/grub-core/kern/partition.c
@@ -109,11 +109,14 @@ grub_partition_map_probe (const grub_partition_map_t partmap,
grub_partition_t
grub_partition_probe (struct grub_disk *disk, const char *str)
{
- grub_partition_t part = 0;
+ grub_partition_t part;
grub_partition_t curpart = 0;
grub_partition_t tail;
const char *ptr;
+ if (str == NULL)
+ return 0;
+
part = tail = disk->partition;
for (ptr = str; *ptr;)
--
2.19.1

View File

@ -0,0 +1,130 @@
From 0397e0712f40fa1d0933da821a0b483b25509680 Mon Sep 17 00:00:00 2001
From: Marco A Benatto <mbenatto@redhat.com>
Date: Mon, 7 Dec 2020 11:53:03 -0300
Subject: [PATCH] disk/ldm: Make sure comp data is freed before exiting from
make_vg()
Several error handling paths in make_vg() do not free comp data before
jumping to fail2 label and returning from the function. This will leak
memory. So, let's fix all issues of that kind.
Fixes: CID 73804
Reference: http://git.savannah.gnu.org/cgit/grub.git/commit/?id=23e39f50ca7a107f6b66396ed4d177a914dee035
Signed-off-by: Marco A Benatto <mbenatto@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/disk/ldm.c | 51 ++++++++++++++++++++++++++++++++++++++------
1 file changed, 44 insertions(+), 7 deletions(-)
diff --git a/grub-core/disk/ldm.c b/grub-core/disk/ldm.c
index 58f8a53..428415f 100644
--- a/grub-core/disk/ldm.c
+++ b/grub-core/disk/ldm.c
@@ -554,7 +554,11 @@ make_vg (grub_disk_t disk,
comp->segments = grub_calloc (comp->segment_alloc,
sizeof (*comp->segments));
if (!comp->segments)
- goto fail2;
+ {
+ grub_free (comp->internal_id);
+ grub_free (comp);
+ goto fail2;
+ }
}
else
{
@@ -562,7 +566,11 @@ make_vg (grub_disk_t disk,
comp->segment_count = 1;
comp->segments = grub_malloc (sizeof (*comp->segments));
if (!comp->segments)
- goto fail2;
+ {
+ grub_free (comp->internal_id);
+ grub_free (comp);
+ goto fail2;
+ }
comp->segments->start_extent = 0;
comp->segments->extent_count = lv->size;
comp->segments->layout = 0;
@@ -574,15 +582,26 @@ make_vg (grub_disk_t disk,
comp->segments->layout = GRUB_RAID_LAYOUT_SYMMETRIC_MASK;
}
else
- goto fail2;
+ {
+ grub_free (comp->segments);
+ grub_free (comp->internal_id);
+ grub_free (comp);
+ goto fail2;
+ }
ptr += *ptr + 1;
ptr++;
if (!(vblk[i].flags & 0x10))
- goto fail2;
+ {
+ grub_free (comp->segments);
+ grub_free (comp->internal_id);
+ grub_free (comp);
+ goto fail2;
+ }
if (ptr >= vblk[i].dynamic + sizeof (vblk[i].dynamic)
|| ptr + *ptr + 1 >= vblk[i].dynamic
+ sizeof (vblk[i].dynamic))
{
+ grub_free (comp->segments);
grub_free (comp->internal_id);
grub_free (comp);
goto fail2;
@@ -592,6 +611,7 @@ make_vg (grub_disk_t disk,
if (ptr + *ptr + 1 >= vblk[i].dynamic
+ sizeof (vblk[i].dynamic))
{
+ grub_free (comp->segments);
grub_free (comp->internal_id);
grub_free (comp);
goto fail2;
@@ -601,7 +621,12 @@ make_vg (grub_disk_t disk,
comp->segments->nodes = grub_calloc (comp->segments->node_alloc,
sizeof (*comp->segments->nodes));
if (!lv->segments->nodes)
- goto fail2;
+ {
+ grub_free (comp->segments);
+ grub_free (comp->internal_id);
+ grub_free (comp);
+ goto fail2;
+ }
}
if (lv->segments->node_alloc == lv->segments->node_count)
@@ -611,11 +636,23 @@ make_vg (grub_disk_t disk,
if (grub_mul (lv->segments->node_alloc, 2, &lv->segments->node_alloc) ||
grub_mul (lv->segments->node_alloc, sizeof (*lv->segments->nodes), &sz))
- goto fail2;
+ {
+ grub_free (comp->segments->nodes);
+ grub_free (comp->segments);
+ grub_free (comp->internal_id);
+ grub_free (comp);
+ goto fail2;
+ }
t = grub_realloc (lv->segments->nodes, sz);
if (!t)
- goto fail2;
+ {
+ grub_free (comp->segments->nodes);
+ grub_free (comp->segments);
+ grub_free (comp->internal_id);
+ grub_free (comp);
+ goto fail2;
+ }
lv->segments->nodes = t;
}
lv->segments->nodes[lv->segments->node_count].pv = 0;
--
2.19.1

View File

@ -0,0 +1,30 @@
From e0cb364719ee0adfc6bc8e27abf4d262075a0062 Mon Sep 17 00:00:00 2001
From: Paulo Flabiano Smorigo <pfsmorigo@canonical.com>
Date: Mon, 7 Dec 2020 10:07:47 -0300
Subject: [PATCH] disk/ldm: If failed then free vg variable too
Fixes: CID 73809
Reference: http://git.savannah.gnu.org/cgit/grub.git/commit/?id=e0b83df5da538d2a38f770e60817b3a4b9d5b4d7
Signed-off-by: Paulo Flabiano Smorigo <pfsmorigo@canonical.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/disk/ldm.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/grub-core/disk/ldm.c b/grub-core/disk/ldm.c
index 428415f..54713f4 100644
--- a/grub-core/disk/ldm.c
+++ b/grub-core/disk/ldm.c
@@ -199,6 +199,7 @@ make_vg (grub_disk_t disk,
{
grub_free (vg->uuid);
grub_free (vg->name);
+ grub_free (vg);
return NULL;
}
grub_memcpy (vg->uuid, label->group_guid, LDM_GUID_STRLEN);
--
2.19.1

View File

@ -0,0 +1,49 @@
From f63402685ccd4bfa9c441d63067853db2a1f6c6a Mon Sep 17 00:00:00 2001
From: Fedora Ninjas <grub2-owner@fedoraproject.org>
Date: Wed, 24 Mar 2021 21:26:10 -0400
Subject: [PATCH] disk/ldm: Fix memory leak on uninserted lv references
The problem here is that the memory allocated to the variable lv is not
yet inserted into the list that is being processed at the label fail2.
As we can already see at line 342, which correctly frees lv before going
to fail2, we should also be doing that at these earlier jumps to fail2.
Fixes: CID 73824
Reference: http://git.savannah.gnu.org/cgit/grub.git/commit/?id=156c281a1625dc73fd350530630c6f2d5673d4f6
---
grub-core/disk/ldm.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/grub-core/disk/ldm.c b/grub-core/disk/ldm.c
index 54713f4..e82e989 100644
--- a/grub-core/disk/ldm.c
+++ b/grub-core/disk/ldm.c
@@ -321,7 +321,10 @@ make_vg (grub_disk_t disk,
lv->visible = 1;
lv->segments = grub_zalloc (sizeof (*lv->segments));
if (!lv->segments)
- goto fail2;
+ {
+ grub_free (lv);
+ goto fail2;
+ }
lv->segments->start_extent = 0;
lv->segments->type = GRUB_DISKFILTER_MIRROR;
lv->segments->node_count = 0;
@@ -329,7 +332,10 @@ make_vg (grub_disk_t disk,
lv->segments->nodes = grub_calloc (lv->segments->node_alloc,
sizeof (*lv->segments->nodes));
if (!lv->segments->nodes)
- goto fail2;
+ {
+ grub_free (lv);
+ goto fail2;
+ }
ptr = vblk[i].dynamic;
if (ptr + *ptr + 1 >= vblk[i].dynamic
+ sizeof (vblk[i].dynamic))
--
2.19.1

View File

@ -0,0 +1,45 @@
From 7dd75b3a9750afa151bf72f3a17123e46ea29456 Mon Sep 17 00:00:00 2001
From: Darren Kenny <darren.kenny@oracle.com>
Date: Fri, 23 Oct 2020 17:09:31 +0000
Subject: [PATCH] hfsplus: Check that the volume name length is valid
HFS+ documentation suggests that the maximum filename and volume name is
255 Unicode characters in length.
So, when converting from big-endian to little-endian, we should ensure
that the name of the volume has a length that is between 0 and 255,
inclusive.
Fixes: CID 73641
Reference: http://git.savannah.gnu.org/cgit/grub.git/commit/?id=2298f6e0d951251bb9ca97d891d1bc8b74515f8c
Signed-off-by: Darren Kenny <darren.kenny@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/fs/hfsplus.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/grub-core/fs/hfsplus.c b/grub-core/fs/hfsplus.c
index 9c4e4c8..8fe7c12 100644
--- a/grub-core/fs/hfsplus.c
+++ b/grub-core/fs/hfsplus.c
@@ -1012,6 +1012,15 @@ grub_hfsplus_label (grub_device_t device, char **label)
grub_hfsplus_btree_recptr (&data->catalog_tree, node, ptr);
label_len = grub_be_to_cpu16 (catkey->namelen);
+
+ /* Ensure that the length is >= 0. */
+ if (label_len < 0)
+ label_len = 0;
+
+ /* Ensure label length is at most 255 Unicode characters. */
+ if (label_len > 255)
+ label_len = 255;
+
label_name = grub_calloc (label_len, sizeof (*label_name));
if (!label_name)
{
--
2.19.1

View File

@ -0,0 +1,44 @@
From c2f4b251269b140e899528f9a824fad5e226d736 Mon Sep 17 00:00:00 2001
From: Darren Kenny <darren.kenny@oracle.com>
Date: Tue, 24 Nov 2020 16:41:49 +0000
Subject: [PATCH] zfs: Fix possible negative shift operation
While it is possible for the return value from zfs_log2() to be zero
(0), it is quite unlikely, given that the previous assignment to blksz
is shifted up by SPA_MINBLOCKSHIFT (9) before 9 is subtracted at the
assignment to epbs.
But, while unlikely during a normal operation, it may be that a carefully
crafted ZFS filesystem could result in a zero (0) value to the
dn_datalbkszsec field, which means that the shift left does nothing
and assigns zero (0) to blksz, resulting in a negative epbs value.
Fixes: CID 73608
Reference: http://git.savannah.gnu.org/cgit/grub.git/commit/?id=a02091834d3e167320d8a262ff04b8e83c5e616d
Signed-off-by: Darren Kenny <darren.kenny@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/fs/zfs/zfs.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c
index 36d0373..0c42cba 100644
--- a/grub-core/fs/zfs/zfs.c
+++ b/grub-core/fs/zfs/zfs.c
@@ -2667,6 +2667,11 @@ dnode_get (dnode_end_t * mdn, grub_uint64_t objnum, grub_uint8_t type,
blksz = grub_zfs_to_cpu16 (mdn->dn.dn_datablkszsec,
mdn->endian) << SPA_MINBLOCKSHIFT;
epbs = zfs_log2 (blksz) - DNODE_SHIFT;
+
+ /* While this should never happen, we should check that epbs is not negative. */
+ if (epbs < 0)
+ epbs = 0;
+
blkid = objnum >> epbs;
idx = objnum & ((1 << epbs) - 1);
--
2.19.1

View File

@ -0,0 +1,123 @@
From d8f1c05738b877a1035bbc6daaae0e99a1210afb Mon Sep 17 00:00:00 2001
From: Paulo Flabiano Smorigo <pfsmorigo@canonical.com>
Date: Mon, 14 Dec 2020 18:54:49 -0300
Subject: [PATCH] zfs: Fix resource leaks while constructing path
There are several exit points in dnode_get_path() that are causing possible
memory leaks.
In the while(1) the correct exit mechanism should not be to do a direct return,
but to instead break out of the loop, setting err first if it is not already set.
The reason behind this is that the dnode_path is a linked list, and while doing
through this loop, it is being allocated and built up - the only way to
correctly unravel it is to traverse it, which is what is being done at the end
of the function outside of the loop.
Several of the existing exit points correctly did a break, but not all so this
change makes that more consistent and should resolve the leaking of memory as
found by Coverity.
Fixes: CID 73741
Reference: http://git.savannah.gnu.org/cgit/grub.git/commit/?id=89bdab965805e8d54d7f75349024e1a11cbe2eb8
Signed-off-by: Paulo Flabiano Smorigo <pfsmorigo@canonical.com>
Signed-off-by: Darren Kenny <darren.kenny@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/fs/zfs/zfs.c | 30 +++++++++++++++++++++---------
1 file changed, 21 insertions(+), 9 deletions(-)
diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c
index 0c42cba..98567a7 100644
--- a/grub-core/fs/zfs/zfs.c
+++ b/grub-core/fs/zfs/zfs.c
@@ -2836,8 +2836,8 @@ dnode_get_path (struct subvolume *subvol, const char *path_in, dnode_end_t *dn,
if (dnode_path->dn.dn.dn_type != DMU_OT_DIRECTORY_CONTENTS)
{
- grub_free (path_buf);
- return grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a directory"));
+ err = grub_error (GRUB_ERR_BAD_FILE_TYPE, N_("not a directory"));
+ break;
}
err = zap_lookup (&(dnode_path->dn), cname, &objnum,
data, subvol->case_insensitive);
@@ -2879,11 +2879,18 @@ dnode_get_path (struct subvolume *subvol, const char *path_in, dnode_end_t *dn,
<< SPA_MINBLOCKSHIFT);
if (blksz == 0)
- return grub_error(GRUB_ERR_BAD_FS, "0-sized block");
+ {
+ err = grub_error (GRUB_ERR_BAD_FS, "0-sized block");
+ break;
+ }
sym_value = grub_malloc (sym_sz);
if (!sym_value)
- return grub_errno;
+ {
+ err = grub_errno;
+ break;
+ }
+
for (block = 0; block < (sym_sz + blksz - 1) / blksz; block++)
{
void *t;
@@ -2893,7 +2900,7 @@ dnode_get_path (struct subvolume *subvol, const char *path_in, dnode_end_t *dn,
if (err)
{
grub_free (sym_value);
- return err;
+ break;
}
movesize = sym_sz - block * blksz;
@@ -2903,6 +2910,8 @@ dnode_get_path (struct subvolume *subvol, const char *path_in, dnode_end_t *dn,
grub_memcpy (sym_value + block * blksz, t, movesize);
grub_free (t);
}
+ if (err)
+ break;
free_symval = 1;
}
path = path_buf = grub_malloc (sym_sz + grub_strlen (oldpath) + 1);
@@ -2911,7 +2920,8 @@ dnode_get_path (struct subvolume *subvol, const char *path_in, dnode_end_t *dn,
grub_free (oldpathbuf);
if (free_symval)
grub_free (sym_value);
- return grub_errno;
+ err = grub_errno;
+ break;
}
grub_memcpy (path, sym_value, sym_sz);
if (free_symval)
@@ -2949,11 +2959,12 @@ dnode_get_path (struct subvolume *subvol, const char *path_in, dnode_end_t *dn,
err = zio_read (bp, dnode_path->dn.endian, &sahdrp, NULL, data);
if (err)
- return err;
+ break;
}
else
{
- return grub_error (GRUB_ERR_BAD_FS, "filesystem is corrupt");
+ err = grub_error (GRUB_ERR_BAD_FS, "filesystem is corrupt");
+ break;
}
hdrsize = SA_HDR_SIZE (((sa_hdr_phys_t *) sahdrp));
@@ -2974,7 +2985,8 @@ dnode_get_path (struct subvolume *subvol, const char *path_in, dnode_end_t *dn,
if (!path_buf)
{
grub_free (oldpathbuf);
- return grub_errno;
+ err = grub_errno;
+ break;
}
grub_memcpy (path, sym_value, sym_sz);
path [sym_sz] = 0;
--
2.19.1

View File

@ -0,0 +1,58 @@
From a005682edd852f7d44903885504d1bfbf313c98a Mon Sep 17 00:00:00 2001
From: Darren Kenny <darren.kenny@oracle.com>
Date: Tue, 8 Dec 2020 22:17:04 +0000
Subject: [PATCH] zfs: Fix possible integer overflows
In all cases the problem is that the value being acted upon by
a left-shift is a 32-bit number which is then being used in the
context of a 64-bit number.
To avoid overflow we ensure that the number being shifted is 64-bit
before the shift is done.
Fixes: CID 73684, CID 73695, CID 73764
Reference: http://git.savannah.gnu.org/cgit/grub.git/commit/?id=302c12ff5714bc455949117c1c9548ccb324d55b
Signed-off-by: Darren Kenny <darren.kenny@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/fs/zfs/zfs.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/grub-core/fs/zfs/zfs.c b/grub-core/fs/zfs/zfs.c
index 98567a7..e3b5f50 100644
--- a/grub-core/fs/zfs/zfs.c
+++ b/grub-core/fs/zfs/zfs.c
@@ -564,7 +564,7 @@ find_bestub (uberblock_phys_t * ub_array,
ubptr = (uberblock_phys_t *) ((grub_properly_aligned_t *) ub_array
+ ((i << ub_shift)
/ sizeof (grub_properly_aligned_t)));
- err = uberblock_verify (ubptr, offset, 1 << ub_shift);
+ err = uberblock_verify (ubptr, offset, (grub_size_t) 1 << ub_shift);
if (err)
{
grub_errno = GRUB_ERR_NONE;
@@ -1543,7 +1543,7 @@ read_device (grub_uint64_t offset, struct grub_zfs_device_desc *desc,
high = grub_divmod64 ((offset >> desc->ashift) + c,
desc->n_children, &devn);
- csize = bsize << desc->ashift;
+ csize = (grub_size_t) bsize << desc->ashift;
if (csize > len)
csize = len;
@@ -1635,8 +1635,8 @@ read_device (grub_uint64_t offset, struct grub_zfs_device_desc *desc,
while (len > 0)
{
- grub_size_t csize;
- csize = ((s / (desc->n_children - desc->nparity))
+ grub_size_t csize = s;
+ csize = ((csize / (desc->n_children - desc->nparity))
<< desc->ashift);
if (csize > len)
csize = len;
--
2.19.1

View File

@ -0,0 +1,37 @@
From 241197448f94998e4bf0bdc32fcb8a93338d11c7 Mon Sep 17 00:00:00 2001
From: Darren Kenny <darren.kenny@oracle.com>
Date: Thu, 26 Nov 2020 10:56:45 +0000
Subject: [PATCH] zfsinfo: Correct a check for error allocating memory
While arguably the check for grub_errno is correct, we should really be
checking the return value from the function since it is always possible
that grub_errno was set elsewhere, making this code behave incorrectly.
Fixes: CID 73668
Reference: http://git.savannah.gnu.org/cgit/grub.git/commit/?id=7aab03418ec6a9b991aa44416cb2585aff4e7972
Signed-off-by: Darren Kenny <darren.kenny@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/fs/zfs/zfsinfo.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/grub-core/fs/zfs/zfsinfo.c b/grub-core/fs/zfs/zfsinfo.c
index c8a28ac..bf29180 100644
--- a/grub-core/fs/zfs/zfsinfo.c
+++ b/grub-core/fs/zfs/zfsinfo.c
@@ -358,8 +358,8 @@ grub_cmd_zfs_bootfs (grub_command_t cmd __attribute__ ((unused)), int argc,
return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("one argument expected"));
devname = grub_file_get_device_name (args[0]);
- if (grub_errno)
- return grub_errno;
+ if (devname == NULL)
+ return GRUB_ERR_OUT_OF_MEMORY;
dev = grub_device_open (devname);
grub_free (devname);
--
2.19.1

View File

@ -0,0 +1,84 @@
From 8f3bc051b74a471f1b083fa80c752dc69566daba Mon Sep 17 00:00:00 2001
From: Darren Kenny <darren.kenny@oracle.com>
Date: Thu, 26 Nov 2020 12:48:07 +0000
Subject: [PATCH] affs: Fix memory leaks
The node structure reference is being allocated but not freed if it
reaches the end of the function. If any of the hooks had returned
a non-zero value, then node would have been copied in to the context
reference, but otherwise node is not stored and should be freed.
Similarly, the call to grub_affs_create_node() replaces the allocated
memory in node with a newly allocated structure, leaking the existing
memory pointed by node.
Finally, when dir->parent is set, then we again replace node with newly
allocated memory, which seems unnecessary when we copy in the values
from dir->parent immediately after.
Fixes: CID 73759
Reference: http://git.savannah.gnu.org/cgit/grub.git/commit/?id=178ac5107389f8e5b32489d743d6824a5ebf342a
Signed-off-by: Darren Kenny <darren.kenny@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/fs/affs.c | 18 ++++++++----------
1 file changed, 8 insertions(+), 10 deletions(-)
diff --git a/grub-core/fs/affs.c b/grub-core/fs/affs.c
index 220b371..230e26a 100644
--- a/grub-core/fs/affs.c
+++ b/grub-core/fs/affs.c
@@ -400,12 +400,12 @@ grub_affs_iterate_dir (grub_fshelp_node_t dir,
{
unsigned int i;
struct grub_affs_file file;
- struct grub_fshelp_node *node = 0;
+ struct grub_fshelp_node *node, *orig_node;
struct grub_affs_data *data = dir->data;
grub_uint32_t *hashtable;
/* Create the directory entries for `.' and `..'. */
- node = grub_zalloc (sizeof (*node));
+ node = orig_node = grub_zalloc (sizeof (*node));
if (!node)
return 1;
@@ -414,9 +414,6 @@ grub_affs_iterate_dir (grub_fshelp_node_t dir,
return 1;
if (dir->parent)
{
- node = grub_zalloc (sizeof (*node));
- if (!node)
- return 1;
*node = *dir->parent;
if (hook ("..", GRUB_FSHELP_DIR, node, hook_data))
return 1;
@@ -456,17 +453,18 @@ grub_affs_iterate_dir (grub_fshelp_node_t dir,
if (grub_affs_create_node (dir, hook, hook_data, &node, &hashtable,
next, &file))
- return 1;
+ {
+ /* Node has been replaced in function. */
+ grub_free (orig_node);
+ return 1;
+ }
next = grub_be_to_cpu32 (file.next);
}
}
- grub_free (hashtable);
- return 0;
-
fail:
- grub_free (node);
+ grub_free (orig_node);
grub_free (hashtable);
return 0;
}
--
2.19.1

View File

@ -0,0 +1,37 @@
From 6ca2b8bcd83f1da666f390274f9d749f2cebe75c Mon Sep 17 00:00:00 2001
From: Darren Kenny <darren.kenny@oracle.com>
Date: Tue, 3 Nov 2020 16:43:37 +0000
Subject: [PATCH] libgcrypt/mpi: Fix possible unintended sign extension
The array of unsigned char gets promoted to a signed 32-bit int before
it is finally promoted to a size_t. There is the possibility that this
may result in the signed-bit being set for the intermediate signed
32-bit int. We should ensure that the promotion is to the correct type
before we bitwise-OR the values.
Fixes: CID 96697
Reference: http://git.savannah.gnu.org/cgit/grub.git/commit/?id=e8814c811132a70f9b55418f7567378a34ad3883
Signed-off-by: Darren Kenny <darren.kenny@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/lib/libgcrypt/mpi/mpicoder.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/grub-core/lib/libgcrypt/mpi/mpicoder.c b/grub-core/lib/libgcrypt/mpi/mpicoder.c
index a3435ed..7ecad27 100644
--- a/grub-core/lib/libgcrypt/mpi/mpicoder.c
+++ b/grub-core/lib/libgcrypt/mpi/mpicoder.c
@@ -458,7 +458,7 @@ gcry_mpi_scan (struct gcry_mpi **ret_mpi, enum gcry_mpi_format format,
if (len && len < 4)
return gcry_error (GPG_ERR_TOO_SHORT);
- n = (s[0] << 24 | s[1] << 16 | s[2] << 8 | s[3]);
+ n = ((size_t)s[0] << 24 | (size_t)s[1] << 16 | (size_t)s[2] << 8 | (size_t)s[3]);
s += 4;
if (len)
len -= 4;
--
2.19.1

View File

@ -0,0 +1,35 @@
From 376207d95a9b4bd824cff943fac190b31f73f9d0 Mon Sep 17 00:00:00 2001
From: Darren Kenny <darren.kenny@oracle.com>
Date: Thu, 26 Nov 2020 10:41:54 +0000
Subject: [PATCH] libgcrypt/mpi: Fix possible NULL dereference
The code in gcry_mpi_scan() assumes that buffer is not NULL, but there
is no explicit check for that, so we add one.
Fixes: CID 73757
Reference: http://git.savannah.gnu.org/cgit/grub.git/commit/?id=ae0f3fabeba7b393113d5dc185b6aff9b728136d
Signed-off-by: Darren Kenny <darren.kenny@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/lib/libgcrypt/mpi/mpicoder.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/grub-core/lib/libgcrypt/mpi/mpicoder.c b/grub-core/lib/libgcrypt/mpi/mpicoder.c
index 7ecad27..6fe3891 100644
--- a/grub-core/lib/libgcrypt/mpi/mpicoder.c
+++ b/grub-core/lib/libgcrypt/mpi/mpicoder.c
@@ -379,6 +379,9 @@ gcry_mpi_scan (struct gcry_mpi **ret_mpi, enum gcry_mpi_format format,
unsigned int len;
int secure = (buffer && gcry_is_secure (buffer));
+ if (!buffer)
+ return gcry_error (GPG_ERR_INV_ARG);
+
if (format == GCRYMPI_FMT_SSH)
len = 0;
else
--
2.19.1

View File

@ -0,0 +1,45 @@
From f15dc85e88c85f08afb67d59099aa150e096264f Mon Sep 17 00:00:00 2001
From: Darren Kenny <darren.kenny@oracle.com>
Date: Thu, 26 Nov 2020 15:31:53 +0000
Subject: [PATCH] syslinux: Fix memory leak while parsing
In syslinux_parse_real() the 2 points where return is being called
didn't release the memory stored in buf which is no longer required.
Fixes: CID 176634
Reference: http://git.savannah.gnu.org/cgit/grub.git/commit/?id=95bc016dba94cab3d398dd74160665915cd08ad6
Signed-off-by: Darren Kenny <darren.kenny@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/lib/syslinux_parse.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/grub-core/lib/syslinux_parse.c b/grub-core/lib/syslinux_parse.c
index de9fda0..ff244d2 100644
--- a/grub-core/lib/syslinux_parse.c
+++ b/grub-core/lib/syslinux_parse.c
@@ -737,7 +737,10 @@ syslinux_parse_real (struct syslinux_menu *menu)
&& grub_strncasecmp ("help", ptr3, ptr4 - ptr3) == 0))
{
if (helptext (ptr5, file, menu))
- return 1;
+ {
+ grub_free (buf);
+ return 1;
+ }
continue;
}
@@ -757,6 +760,7 @@ syslinux_parse_real (struct syslinux_menu *menu)
}
fail:
grub_file_close (file);
+ grub_free (buf);
return err;
}
--
2.19.1

View File

@ -0,0 +1,54 @@
From 2cf1f83fcb5e816144f4352f153a07219e2c2e5a Mon Sep 17 00:00:00 2001
From: Darren Kenny <darren.kenny@oracle.com>
Date: Fri, 4 Dec 2020 18:56:48 +0000
Subject: [PATCH] normal/completion: Fix leaking of memory when processing a
completion
It is possible for the code to reach the end of the function without
freeing the memory allocated to argv and argc still to be 0.
We should always call grub_free(argv). The grub_free() will handle
a NULL argument correctly if it reaches that code without the memory
being allocated.
Fixes: CID 96672
Reference: http://git.savannah.gnu.org/cgit/grub.git/commit/?id=9213575b7a95b514bce80be5964a28d407d7d56d
Signed-off-by: Darren Kenny <darren.kenny@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/normal/completion.c | 10 ++++------
1 file changed, 4 insertions(+), 6 deletions(-)
diff --git a/grub-core/normal/completion.c b/grub-core/normal/completion.c
index c07100a..18cadfa 100644
--- a/grub-core/normal/completion.c
+++ b/grub-core/normal/completion.c
@@ -401,8 +401,8 @@ char *
grub_normal_do_completion (char *buf, int *restore,
void (*hook) (const char *, grub_completion_type_t, int))
{
- int argc;
- char **argv;
+ int argc = 0;
+ char **argv = NULL;
/* Initialize variables. */
match = 0;
@@ -517,10 +517,8 @@ grub_normal_do_completion (char *buf, int *restore,
fail:
if (argc != 0)
- {
- grub_free (argv[0]);
- grub_free (argv);
- }
+ grub_free (argv[0]);
+ grub_free (argv);
grub_free (match);
grub_errno = GRUB_ERR_NONE;
--
2.19.1

View File

@ -0,0 +1,58 @@
From d172ca13c6fdf9a3daf1539eec9fd6b3a17dc16b Mon Sep 17 00:00:00 2001
From: Fedora Ninjas <grub2-owner@fedoraproject.org>
Date: Tue, 1 Dec 2020 23:41:24 +0000
Subject: [PATCH] commands/hashsum: Fix a memory leak
check_list() uses grub_file_getline(), which allocates a buffer.
If the hash list file contains invalid lines, the function leaks
this buffer when it returns an error.
Fixes: CID 176635
Reference: http://git.savannah.gnu.org/cgit/grub.git/commit/?id=8b6f528e52e18b7a69f90b8dc3671d7b1147d9f3
Signed-off-by: Chris Coulson <chris.coulson@canonical.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/commands/hashsum.c | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/grub-core/commands/hashsum.c b/grub-core/commands/hashsum.c
index 456ba90..b8a22b0 100644
--- a/grub-core/commands/hashsum.c
+++ b/grub-core/commands/hashsum.c
@@ -128,11 +128,17 @@ check_list (const gcry_md_spec_t *hash, const char *hashfilename,
high = hextoval (*p++);
low = hextoval (*p++);
if (high < 0 || low < 0)
- return grub_error (GRUB_ERR_BAD_FILE_TYPE, "invalid hash list");
+ {
+ grub_free (buf);
+ return grub_error (GRUB_ERR_BAD_FILE_TYPE, "invalid hash list");
+ }
expected[i] = (high << 4) | low;
}
if ((p[0] != ' ' && p[0] != '\t') || (p[1] != ' ' && p[1] != '\t'))
- return grub_error (GRUB_ERR_BAD_FILE_TYPE, "invalid hash list");
+ {
+ grub_free (buf);
+ return grub_error (GRUB_ERR_BAD_FILE_TYPE, "invalid hash list");
+ }
p += 2;
if (prefix)
{
@@ -140,7 +146,10 @@ check_list (const gcry_md_spec_t *hash, const char *hashfilename,
filename = grub_xasprintf ("%s/%s", prefix, p);
if (!filename)
- return grub_errno;
+ {
+ grub_free (buf);
+ return grub_errno;
+ }
file = grub_file_open (filename, GRUB_FILE_TYPE_TO_HASH
| (!uncompress ? GRUB_FILE_TYPE_NO_DECOMPRESS
: GRUB_FILE_TYPE_NONE));
--
2.19.1

View File

@ -0,0 +1,96 @@
From cbd9c660d75335e49d928b37a1c4b3c85aee6df3 Mon Sep 17 00:00:00 2001
From: Darren Kenny <darren.kenny@oracle.com>
Date: Tue, 8 Dec 2020 21:14:31 +0000
Subject: [PATCH] video/efi_gop: Remove unnecessary return value of
grub_video_gop_fill_mode_info()
The return value of grub_video_gop_fill_mode_info() is never able to be
anything other than GRUB_ERR_NONE. So, rather than continue to return
a value and checking it each time, it is more correct to redefine the
function to not return anything and remove checks of its return value
altogether.
Fixes: CID 96701
Reference: http://git.savannah.gnu.org/cgit/grub.git/commit/?id=fc5951d3b1616055ef81a019a5affc09d13344d0
Signed-off-by: Darren Kenny <darren.kenny@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/video/efi_gop.c | 25 ++++++-------------------
1 file changed, 6 insertions(+), 19 deletions(-)
diff --git a/grub-core/video/efi_gop.c b/grub-core/video/efi_gop.c
index be446f8..e6c9372 100644
--- a/grub-core/video/efi_gop.c
+++ b/grub-core/video/efi_gop.c
@@ -235,7 +235,7 @@ grub_video_gop_fill_real_mode_info (unsigned mode,
return GRUB_ERR_NONE;
}
-static grub_err_t
+static void
grub_video_gop_fill_mode_info (unsigned mode,
struct grub_efi_gop_mode_info *in,
struct grub_video_mode_info *out)
@@ -260,8 +260,6 @@ grub_video_gop_fill_mode_info (unsigned mode,
out->blit_format = GRUB_VIDEO_BLIT_FORMAT_BGRA_8888;
out->mode_type |= (GRUB_VIDEO_MODE_TYPE_DOUBLE_BUFFERED
| GRUB_VIDEO_MODE_TYPE_UPDATING_SWAP);
-
- return GRUB_ERR_NONE;
}
static int
@@ -274,7 +272,6 @@ grub_video_gop_iterate (int (*hook) (const struct grub_video_mode_info *info, vo
grub_efi_uintn_t size;
grub_efi_status_t status;
struct grub_efi_gop_mode_info *info = NULL;
- grub_err_t err;
struct grub_video_mode_info mode_info;
status = efi_call_4 (gop->query_mode, gop, mode, &size, &info);
@@ -285,12 +282,7 @@ grub_video_gop_iterate (int (*hook) (const struct grub_video_mode_info *info, vo
continue;
}
- err = grub_video_gop_fill_mode_info (mode, info, &mode_info);
- if (err)
- {
- grub_errno = GRUB_ERR_NONE;
- continue;
- }
+ grub_video_gop_fill_mode_info (mode, info, &mode_info);
if (hook (&mode_info, hook_arg))
return 1;
}
@@ -474,13 +466,8 @@ grub_video_gop_setup (unsigned int width, unsigned int height,
info = gop->mode->info;
- err = grub_video_gop_fill_mode_info (gop->mode->mode, info,
- &framebuffer.mode_info);
- if (err)
- {
- grub_dprintf ("video", "GOP: couldn't fill mode info\n");
- return err;
- }
+ grub_video_gop_fill_mode_info (gop->mode->mode, info,
+ &framebuffer.mode_info);
framebuffer.ptr = (void *) (grub_addr_t) gop->mode->fb_base;
framebuffer.offscreen
@@ -494,8 +481,8 @@ grub_video_gop_setup (unsigned int width, unsigned int height,
{
grub_dprintf ("video", "GOP: couldn't allocate shadow\n");
grub_errno = 0;
- err = grub_video_gop_fill_mode_info (gop->mode->mode, info,
- &framebuffer.mode_info);
+ grub_video_gop_fill_mode_info (gop->mode->mode, info,
+ &framebuffer.mode_info);
buffer = framebuffer.ptr;
}
--
2.19.1

View File

@ -0,0 +1,80 @@
From 7ad0a046156daf7dfb10018a1c5804e6ec668c6b Mon Sep 17 00:00:00 2001
From: Darren Kenny <darren.kenny@oracle.com>
Date: Wed, 4 Nov 2020 15:10:51 +0000
Subject: [PATCH] video/fb/fbfill: Fix potential integer overflow
The multiplication of 2 unsigned 32-bit integers may overflow before
promotion to unsigned 64-bit. We should ensure that the multiplication
is done with overflow detection. Additionally, use grub_sub() for
subtraction.
Fixes: CID 73640, CID 73697, CID 73702, CID 73823
Reference: http://git.savannah.gnu.org/cgit/grub.git/commit/?id=7ce3259f67ac2cd93acb0ec0080c24b3b69e66c6
Signed-off-by: Darren Kenny <darren.kenny@oracle.com>
Signed-off-by: Marco A Benatto <mbenatto@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/video/fb/fbfill.c | 17 +++++++++++++----
1 file changed, 13 insertions(+), 4 deletions(-)
diff --git a/grub-core/video/fb/fbfill.c b/grub-core/video/fb/fbfill.c
index 11816d0..a37acd1 100644
--- a/grub-core/video/fb/fbfill.c
+++ b/grub-core/video/fb/fbfill.c
@@ -31,6 +31,7 @@
#include <grub/fbfill.h>
#include <grub/fbutil.h>
#include <grub/types.h>
+#include <grub/safemath.h>
#include <grub/video.h>
/* Generic filler that works for every supported mode. */
@@ -61,7 +62,9 @@ grub_video_fbfill_direct32 (struct grub_video_fbblit_info *dst,
/* Calculate the number of bytes to advance from the end of one line
to the beginning of the next line. */
- rowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
+ if (grub_mul (dst->mode_info->bytes_per_pixel, width, &rowskip) ||
+ grub_sub (dst->mode_info->pitch, rowskip, &rowskip))
+ return;
/* Get the start address. */
dstptr = grub_video_fb_get_video_ptr (dst, x, y);
@@ -98,7 +101,9 @@ grub_video_fbfill_direct24 (struct grub_video_fbblit_info *dst,
#endif
/* Calculate the number of bytes to advance from the end of one line
to the beginning of the next line. */
- rowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
+ if (grub_mul (dst->mode_info->bytes_per_pixel, width, &rowskip) ||
+ grub_sub (dst->mode_info->pitch, rowskip, &rowskip))
+ return;
/* Get the start address. */
dstptr = grub_video_fb_get_video_ptr (dst, x, y);
@@ -131,7 +136,9 @@ grub_video_fbfill_direct16 (struct grub_video_fbblit_info *dst,
/* Calculate the number of bytes to advance from the end of one line
to the beginning of the next line. */
- rowskip = (dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width);
+ if (grub_mul (dst->mode_info->bytes_per_pixel, width, &rowskip) ||
+ grub_sub (dst->mode_info->pitch, rowskip, &rowskip))
+ return;
/* Get the start address. */
dstptr = grub_video_fb_get_video_ptr (dst, x, y);
@@ -161,7 +168,9 @@ grub_video_fbfill_direct8 (struct grub_video_fbblit_info *dst,
/* Calculate the number of bytes to advance from the end of one line
to the beginning of the next line. */
- rowskip = dst->mode_info->pitch - dst->mode_info->bytes_per_pixel * width;
+ if (grub_mul (dst->mode_info->bytes_per_pixel, width, &rowskip) ||
+ grub_sub (dst->mode_info->pitch, rowskip, &rowskip))
+ return;
/* Get the start address. */
dstptr = grub_video_fb_get_video_ptr (dst, x, y);
--
2.19.1

View File

@ -0,0 +1,106 @@
From 57f8f7adde0a9c47e56d8619d2d2d14c5e5ca172 Mon Sep 17 00:00:00 2001
From: Darren Kenny <darren.kenny@oracle.com>
Date: Wed, 4 Nov 2020 14:43:44 +0000
Subject: [PATCH] video/fb/video_fb: Fix multiple integer overflows
The calculation of the unsigned 64-bit value is being generated by
multiplying 2, signed or unsigned, 32-bit integers which may overflow
before promotion to unsigned 64-bit. Fix all of them.
Fixes: CID 73703, CID 73767, CID 73833
Reference: http://git.savannah.gnu.org/cgit/grub.git/commit/?id=08e098b1dbf01e96376f594b337491bc4cfa48dd
Signed-off-by: Darren Kenny <darren.kenny@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/video/fb/video_fb.c | 52 ++++++++++++++++++++++++-----------
1 file changed, 36 insertions(+), 16 deletions(-)
diff --git a/grub-core/video/fb/video_fb.c b/grub-core/video/fb/video_fb.c
index 1a602c8..1c9a138 100644
--- a/grub-core/video/fb/video_fb.c
+++ b/grub-core/video/fb/video_fb.c
@@ -25,6 +25,7 @@
#include <grub/fbutil.h>
#include <grub/bitmap.h>
#include <grub/dl.h>
+#include <grub/safemath.h>
GRUB_MOD_LICENSE ("GPLv3+");
@@ -1417,15 +1418,23 @@ doublebuf_blit_update_screen (void)
{
if (framebuffer.current_dirty.first_line
<= framebuffer.current_dirty.last_line)
- grub_memcpy ((char *) framebuffer.pages[0]
- + framebuffer.current_dirty.first_line
- * framebuffer.back_target->mode_info.pitch,
- (char *) framebuffer.back_target->data
- + framebuffer.current_dirty.first_line
- * framebuffer.back_target->mode_info.pitch,
- framebuffer.back_target->mode_info.pitch
- * (framebuffer.current_dirty.last_line
- - framebuffer.current_dirty.first_line));
+ {
+ grub_size_t copy_size;
+
+ if (grub_sub (framebuffer.current_dirty.last_line,
+ framebuffer.current_dirty.first_line, &copy_size) ||
+ grub_mul (framebuffer.back_target->mode_info.pitch, copy_size, &copy_size))
+ {
+ /* Shouldn't happen, but if it does we've a bug. */
+ return GRUB_ERR_BUG;
+ }
+
+ grub_memcpy ((char *) framebuffer.pages[0] + framebuffer.current_dirty.first_line *
+ framebuffer.back_target->mode_info.pitch,
+ (char *) framebuffer.back_target->data + framebuffer.current_dirty.first_line *
+ framebuffer.back_target->mode_info.pitch,
+ copy_size);
+ }
framebuffer.current_dirty.first_line
= framebuffer.back_target->mode_info.height;
framebuffer.current_dirty.last_line = 0;
@@ -1439,7 +1448,7 @@ grub_video_fb_doublebuf_blit_init (struct grub_video_fbrender_target **back,
volatile void *framebuf)
{
grub_err_t err;
- grub_size_t page_size = mode_info.pitch * mode_info.height;
+ grub_size_t page_size = (grub_size_t) mode_info.pitch * mode_info.height;
framebuffer.offscreen_buffer = grub_zalloc (page_size);
if (! framebuffer.offscreen_buffer)
@@ -1482,12 +1491,23 @@ doublebuf_pageflipping_update_screen (void)
last_line = framebuffer.previous_dirty.last_line;
if (first_line <= last_line)
- grub_memcpy ((char *) framebuffer.pages[framebuffer.render_page]
- + first_line * framebuffer.back_target->mode_info.pitch,
- (char *) framebuffer.back_target->data
- + first_line * framebuffer.back_target->mode_info.pitch,
- framebuffer.back_target->mode_info.pitch
- * (last_line - first_line));
+ {
+ grub_size_t copy_size;
+
+ if (grub_sub (last_line, first_line, &copy_size) ||
+ grub_mul (framebuffer.back_target->mode_info.pitch, copy_size, &copy_size))
+ {
+ /* Shouldn't happen, but if it does we've a bug. */
+ return GRUB_ERR_BUG;
+ }
+
+ grub_memcpy ((char *) framebuffer.pages[framebuffer.render_page] + first_line *
+ framebuffer.back_target->mode_info.pitch,
+ (char *) framebuffer.back_target->data + first_line *
+ framebuffer.back_target->mode_info.pitch,
+ copy_size);
+ }
+
framebuffer.previous_dirty = framebuffer.current_dirty;
framebuffer.current_dirty.first_line
= framebuffer.back_target->mode_info.height;
--
2.19.1

View File

@ -0,0 +1,41 @@
From 12e144d4c50cee2e773f9994921524e1a342b565 Mon Sep 17 00:00:00 2001
From: Darren Kenny <darren.kenny@oracle.com>
Date: Fri, 4 Dec 2020 14:51:30 +0000
Subject: [PATCH] video/fb/video_fb: Fix possible integer overflow
It is minimal possibility that the values being used here will overflow.
So, change the code to use the safemath function grub_mul() to ensure
that doesn't happen.
Fixes: CID 73761
Reference: http://git.savannah.gnu.org/cgit/grub.git/commit/?id=08413f2f4edec0e2d9bf15f836f6ee5ca2e379cb
Signed-off-by: Darren Kenny <darren.kenny@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/video/fb/video_fb.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/grub-core/video/fb/video_fb.c b/grub-core/video/fb/video_fb.c
index 1c9a138..ae6b89f 100644
--- a/grub-core/video/fb/video_fb.c
+++ b/grub-core/video/fb/video_fb.c
@@ -1537,7 +1537,13 @@ doublebuf_pageflipping_init (struct grub_video_mode_info *mode_info,
volatile void *page1_ptr)
{
grub_err_t err;
- grub_size_t page_size = mode_info->pitch * mode_info->height;
+ grub_size_t page_size = 0;
+
+ if (grub_mul (mode_info->pitch, mode_info->height, &page_size))
+ {
+ /* Shouldn't happen, but if it does we've a bug. */
+ return GRUB_ERR_BUG;
+ }
framebuffer.offscreen_buffer = grub_malloc (page_size);
if (! framebuffer.offscreen_buffer)
--
2.19.1

View File

@ -0,0 +1,40 @@
From 7317421fa3343bc1aaf2a631a26b17a3a7bff9a7 Mon Sep 17 00:00:00 2001
From: Darren Kenny <darren.kenny@oracle.com>
Date: Fri, 4 Dec 2020 15:39:00 +0000
Subject: [PATCH] video/readers/jpeg: Test for an invalid next marker reference
from a jpeg file
While it may never happen, and potentially could be caught at the end of
the function, it is worth checking up front for a bad reference to the
next marker just in case of a maliciously crafted file being provided.
Fixes: CID 73694
Reference: http://git.savannah.gnu.org/cgit/grub.git/commit/?id=5f5eb7ca8e971227e95745abe541df3e1509360e
Signed-off-by: Darren Kenny <darren.kenny@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/video/readers/jpeg.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/grub-core/video/readers/jpeg.c b/grub-core/video/readers/jpeg.c
index 31359a4..0b6ce3c 100644
--- a/grub-core/video/readers/jpeg.c
+++ b/grub-core/video/readers/jpeg.c
@@ -253,6 +253,12 @@ grub_jpeg_decode_quan_table (struct grub_jpeg_data *data)
next_marker = data->file->offset;
next_marker += grub_jpeg_get_word (data);
+ if (next_marker > data->file->size)
+ {
+ /* Should never be set beyond the size of the file. */
+ return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: invalid next reference");
+ }
+
while (data->file->offset + sizeof (data->quan_table[id]) + 1
<= next_marker)
{
--
2.19.1

View File

@ -0,0 +1,36 @@
From 19fdfa6f93f586fd7d3ce0be0a94f90cb6bbf09d Mon Sep 17 00:00:00 2001
From: Darren Kenny <darren.kenny@oracle.com>
Date: Mon, 7 Dec 2020 14:44:47 +0000
Subject: [PATCH] gfxmenu/gui_list: Remove code that coverity is flagging as
dead
The test of value for NULL before calling grub_strdup() is not required,
since the if condition prior to this has already tested for value being
NULL and cannot reach this code if it is.
Fixes: CID 73659
Reference: http://git.savannah.gnu.org/cgit/grub.git/commit/?id=4a1aa5917595650efbd46b581368c470ebee42ab
Signed-off-by: Darren Kenny <darren.kenny@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/gfxmenu/gui_list.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/grub-core/gfxmenu/gui_list.c b/grub-core/gfxmenu/gui_list.c
index 01477cd..df334a6 100644
--- a/grub-core/gfxmenu/gui_list.c
+++ b/grub-core/gfxmenu/gui_list.c
@@ -771,7 +771,7 @@ list_set_property (void *vself, const char *name, const char *value)
{
self->need_to_recreate_boxes = 1;
grub_free (self->selected_item_box_pattern);
- self->selected_item_box_pattern = value ? grub_strdup (value) : 0;
+ self->selected_item_box_pattern = grub_strdup (value);
self->selected_item_box_pattern_inherit = 0;
}
}
--
2.19.1

View File

@ -0,0 +1,49 @@
From 57e99b2d5e72074ee07264e6c167e444b5419c78 Mon Sep 17 00:00:00 2001
From: Darren Kenny <darren.kenny@oracle.com>
Date: Tue, 8 Dec 2020 21:47:13 +0000
Subject: [PATCH] loader/bsd: Check for NULL arg up-front
The code in the next block suggests that it is possible for .set to be
true but .arg may still be NULL.
This code assumes that it is never NULL, yet later is testing if it is
NULL - that is inconsistent.
So we should check first if .arg is not NULL, and remove this check that
is being flagged by Coverity since it is no longer required.
Fixes: CID 292471
Reference: http://git.savannah.gnu.org/cgit/grub.git/commit/?id=5d5391b0a05abe76e04c1eb68dcc6cbef5326c4a
Signed-off-by: Darren Kenny <darren.kenny@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/loader/i386/bsd.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/grub-core/loader/i386/bsd.c b/grub-core/loader/i386/bsd.c
index ff98fb7..a1c0abf 100644
--- a/grub-core/loader/i386/bsd.c
+++ b/grub-core/loader/i386/bsd.c
@@ -1606,7 +1606,7 @@ grub_cmd_openbsd (grub_extcmd_context_t ctxt, int argc, char *argv[])
kernel_type = KERNEL_TYPE_OPENBSD;
bootflags = grub_bsd_parse_flags (ctxt->state, openbsd_flags);
- if (ctxt->state[OPENBSD_ROOT_ARG].set)
+ if (ctxt->state[OPENBSD_ROOT_ARG].set && ctxt->state[OPENBSD_ROOT_ARG].arg != NULL)
{
const char *arg = ctxt->state[OPENBSD_ROOT_ARG].arg;
unsigned type, unit, part;
@@ -1623,7 +1623,7 @@ grub_cmd_openbsd (grub_extcmd_context_t ctxt, int argc, char *argv[])
"unknown disk type name");
unit = grub_strtoul (arg, &arg, 10);
- if (! (arg && *arg >= 'a' && *arg <= 'z'))
+ if (! (*arg >= 'a' && *arg <= 'z'))
return grub_error (GRUB_ERR_BAD_ARGUMENT,
"only device specifications of form "
"<type><number><lowercase letter> are supported");
--
2.19.1

View File

@ -0,0 +1,40 @@
From 9c80754151a398650d7467a94b6c0ca6160f21f8 Mon Sep 17 00:00:00 2001
From: Darren Kenny <darren.kenny@oracle.com>
Date: Thu, 26 Nov 2020 12:53:10 +0000
Subject: [PATCH] loader/xnu: Fix memory leak
he code here is finished with the memory stored in name, but it only
frees it if there curvalue is valid, while it could actually free it
regardless.
The fix is a simple relocation of the grub_free() to before the test
of curvalue.
Fixes: CID 96646
Reference: http://git.savannah.gnu.org/cgit/grub.git/commit/?id=bcb59ece3263d118510c4440c4da0950f224bb7f
Signed-off-by: Darren Kenny <darren.kenny@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/loader/xnu.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/grub-core/loader/xnu.c b/grub-core/loader/xnu.c
index 36481d8..9d40908 100644
--- a/grub-core/loader/xnu.c
+++ b/grub-core/loader/xnu.c
@@ -1392,9 +1392,9 @@ grub_xnu_fill_devicetree (void)
name[len] = 0;
curvalue = grub_xnu_create_value (curkey, name);
+ grub_free (name);
if (!curvalue)
return grub_errno;
- grub_free (name);
data = grub_malloc (grub_strlen (var->value) + 1);
if (!data)
--
2.19.1

View File

@ -0,0 +1,71 @@
From 0699bb82f8c260161ff11cf28024c7e25f0a5dd5 Mon Sep 17 00:00:00 2001
From: Fedora Ninjas <grub2-owner@fedoraproject.org>
Date: Thu, 25 Mar 2021 03:58:28 -0400
Subject: [PATCH] loader/xnu: Free driverkey data when an error is detected in
grub_xnu_writetree_toheap()
---
grub-core/loader/xnu.c | 24 ++++++++++++++++++++----
1 file changed, 20 insertions(+), 4 deletions(-)
diff --git a/grub-core/loader/xnu.c b/grub-core/loader/xnu.c
index 9d40908..8efcbd2 100644
--- a/grub-core/loader/xnu.c
+++ b/grub-core/loader/xnu.c
@@ -228,26 +228,33 @@ grub_xnu_writetree_toheap (grub_addr_t *target, grub_size_t *size)
if (! memorymap)
return grub_errno;
- driverkey = (struct grub_xnu_devtree_key *) grub_malloc (sizeof (*driverkey));
+ driverkey = (struct grub_xnu_devtree_key *) grub_zalloc (sizeof (*driverkey));
if (! driverkey)
return grub_errno;
driverkey->name = grub_strdup ("DeviceTree");
if (! driverkey->name)
- return grub_errno;
+ {
+ err = grub_errno;
+ goto fail;
+ }
+
driverkey->datasize = sizeof (*extdesc);
driverkey->next = memorymap->first_child;
memorymap->first_child = driverkey;
driverkey->data = extdesc
= (struct grub_xnu_extdesc *) grub_malloc (sizeof (*extdesc));
if (! driverkey->data)
- return grub_errno;
+ {
+ err = grub_errno;
+ goto fail;
+ }
/* Allocate the space based on the size with dummy value. */
*size = grub_xnu_writetree_get_size (grub_xnu_devtree_root, "/");
err = grub_xnu_heap_malloc (ALIGN_UP (*size + 1, GRUB_XNU_PAGESIZE),
&src, target);
if (err)
- return err;
+ goto fail;
/* Put real data in the dummy. */
extdesc->addr = *target;
@@ -256,6 +263,15 @@ grub_xnu_writetree_toheap (grub_addr_t *target, grub_size_t *size)
/* Write the tree to heap. */
grub_xnu_writetree_toheap_real (src, grub_xnu_devtree_root, "/");
return GRUB_ERR_NONE;
+
+fail:
+ memorymap->first_child = NULL;
+
+ grub_free (driverkey->data);
+ grub_free (driverkey->name);
+ grub_free (driverkey);
+
+ return err;
}
/* Find a key or value in parent key. */
--
2.19.1

View File

@ -0,0 +1,44 @@
From 650d479e6c326c8579b3fd4fa13d99bf3a775bf2 Mon Sep 17 00:00:00 2001
From: Paulo Flabiano Smorigo <pfsmorigo@canonical.com>
Date: Mon, 30 Nov 2020 10:36:00 -0300
Subject: [PATCH] loader/xnu: Check if pointer is NULL before using it
Fixes: CID 73654
Reference: http://git.savannah.gnu.org/cgit/grub.git/commit/?id=7c8a2b5d1421a0f2a33d33531f7561f3da93b844
Signed-off-by: Paulo Flabiano Smorigo <pfsmorigo@canonical.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/loader/xnu.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/grub-core/loader/xnu.c b/grub-core/loader/xnu.c
index 8efcbd2..74f3b4f 100644
--- a/grub-core/loader/xnu.c
+++ b/grub-core/loader/xnu.c
@@ -671,6 +671,9 @@ grub_xnu_load_driver (char *infoplistname, grub_file_t binaryfile,
char *name, *nameend;
int namelen;
+ if (infoplistname == NULL)
+ return grub_error (GRUB_ERR_BAD_FILENAME, N_("missing p-list filename"));
+
name = get_name_ptr (infoplistname);
nameend = grub_strchr (name, '/');
@@ -702,10 +705,7 @@ grub_xnu_load_driver (char *infoplistname, grub_file_t binaryfile,
else
macho = 0;
- if (infoplistname)
- infoplist = grub_file_open (infoplistname, GRUB_FILE_TYPE_XNU_INFO_PLIST);
- else
- infoplist = 0;
+ infoplist = grub_file_open (infoplistname, GRUB_FILE_TYPE_XNU_INFO_PLIST);
grub_errno = GRUB_ERR_NONE;
if (infoplist)
{
--
2.19.1

View File

@ -0,0 +1,43 @@
From 11c0550c2a5e0ff79b21294e9decf3c1da66e43b Mon Sep 17 00:00:00 2001
From: Daniel Kiper <daniel.kiper@oracle.com>
Date: Thu, 25 Feb 2021 18:35:01 +0100
Subject: [PATCH] util/grub-install: Fix NULL pointer dereferences
Two grub_device_open() calls does not have associated NULL checks
for returned values. Fix that and appease the Coverity.
Fixes: CID 314583
Reference: http://git.savannah.gnu.org/cgit/grub.git/commit/?id=8b3a95655b4391122e7b0315d8cc6f876caf8183
Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
---
util/grub-install.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/util/grub-install.c b/util/grub-install.c
index dddb757..d4fd549 100644
--- a/util/grub-install.c
+++ b/util/grub-install.c
@@ -1837,6 +1837,8 @@ main (int argc, char *argv[])
fill_core_services (core_services);
ins_dev = grub_device_open (install_drive);
+ if (ins_dev == NULL)
+ grub_util_error ("%s", grub_errmsg);
bless (ins_dev, core_services, 0);
@@ -1937,6 +1939,8 @@ main (int argc, char *argv[])
fill_core_services(core_services);
ins_dev = grub_device_open (install_drive);
+ if (ins_dev == NULL)
+ grub_util_error ("%s", grub_errmsg);
bless (ins_dev, boot_efi, 1);
if (!removable && update_nvram)
--
2.19.1

View File

@ -0,0 +1,48 @@
From 9f3d2f056a602df45e41646cf75bd4f379ccc94c Mon Sep 17 00:00:00 2001
From: Darren Kenny <darren.kenny@oracle.com>
Date: Thu, 5 Nov 2020 14:33:50 +0000
Subject: [PATCH] util/grub-editenv: Fix incorrect casting of a signed value
The return value of ftell() may be negative (-1) on error. While it is
probably unlikely to occur, we should not blindly cast to an unsigned
value without first testing that it is not negative.
Fixes: CID 73856
Reference: http://git.savannah.gnu.org/cgit/grub.git/commit/?id=5dc41edc4eba259c6043ae7698c245ec1baaacc6
Signed-off-by: Darren Kenny <darren.kenny@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
util/grub-editenv.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/util/grub-editenv.c b/util/grub-editenv.c
index d848038..948eec8 100644
--- a/util/grub-editenv.c
+++ b/util/grub-editenv.c
@@ -128,6 +128,7 @@ open_envblk_file (const char *name)
{
FILE *fp;
char *buf;
+ long loc;
size_t size;
grub_envblk_t envblk;
@@ -146,7 +147,12 @@ open_envblk_file (const char *name)
grub_util_error (_("cannot seek `%s': %s"), name,
strerror (errno));
- size = (size_t) ftell (fp);
+ loc = ftell (fp);
+ if (loc < 0)
+ grub_util_error (_("cannot get file location `%s': %s"), name,
+ strerror (errno));
+
+ size = (size_t) loc;
if (fseek (fp, 0, SEEK_SET) < 0)
grub_util_error (_("cannot seek `%s': %s"), name,
--
2.19.1

View File

@ -0,0 +1,52 @@
From 97292a12c766871e51e3efb2b04948841c1458df Mon Sep 17 00:00:00 2001
From: Darren Kenny <darren.kenny@oracle.com>
Date: Fri, 4 Dec 2020 15:04:28 +0000
Subject: [PATCH] util/glue-efi: Fix incorrect use of a possibly negative value
It is possible for the ftell() function to return a negative value,
although it is fairly unlikely here, we should be checking for
a negative value before we assign it to an unsigned value.
Fixes: CID 73744
Reference: http://git.savannah.gnu.org/cgit/grub.git/commit/?id=1641d74e16f9d1ca35ba1a87ee4a0bf3afa48e72
Signed-off-by: Darren Kenny <darren.kenny@oracle.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
util/glue-efi.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/util/glue-efi.c b/util/glue-efi.c
index 68f5316..de0fa6d 100644
--- a/util/glue-efi.c
+++ b/util/glue-efi.c
@@ -39,13 +39,23 @@ write_fat (FILE *in32, FILE *in64, FILE *out, const char *out_filename,
struct grub_macho_fat_header head;
struct grub_macho_fat_arch arch32, arch64;
grub_uint32_t size32, size64;
+ long size;
char *buf;
fseek (in32, 0, SEEK_END);
- size32 = ftell (in32);
+ size = ftell (in32);
+ if (size < 0)
+ grub_util_error ("cannot get end of input file '%s': %s",
+ name32, strerror (errno));
+ size32 = (grub_uint32_t) size;
fseek (in32, 0, SEEK_SET);
+
fseek (in64, 0, SEEK_END);
- size64 = ftell (in64);
+ size = ftell (in64);
+ if (size < 0)
+ grub_util_error ("cannot get end of input file '%s': %s",
+ name64, strerror (errno));
+ size64 = (grub_uint64_t) size;
fseek (in64, 0, SEEK_SET);
head.magic = grub_cpu_to_le32_compile_time (GRUB_MACHO_FAT_EFI_MAGIC);
--
2.19.1

View File

@ -0,0 +1,30 @@
From 502ceabcd34bd4fe666195142694d15f863bc6dc Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Fri, 3 Apr 2020 23:05:13 +1100
Subject: [PATCH] script/execute: Fix NULL dereference in
grub_script_execute_cmdline()
Reference: http://git.savannah.gnu.org/cgit/grub.git/commit/?id=41ae93b2e6c75453514629bcfe684300e3aec0ce
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/script/execute.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/grub-core/script/execute.c b/grub-core/script/execute.c
index d2f02cc..b6e326c 100644
--- a/grub-core/script/execute.c
+++ b/grub-core/script/execute.c
@@ -978,7 +978,7 @@ grub_script_execute_cmdline (struct grub_script_cmd *cmd)
struct grub_script_argv argv = { 0, 0, 0 };
/* Lookup the command. */
- if (grub_script_arglist_to_argv (cmdline->arglist, &argv) || ! argv.args[0])
+ if (grub_script_arglist_to_argv (cmdline->arglist, &argv) || ! argv.args || ! argv.args[0])
return grub_errno;
for (i = 0; i < argv.argc; i++)
--
2.19.1

View File

@ -0,0 +1,35 @@
From 5955a69bc4281d159a19424917382aa32faa6e95 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Mon, 11 Jan 2021 16:57:37 +1100
Subject: [PATCH] commands/ls: Require device_name is not NULL before printing
This can be triggered with:
ls -l (0 0*)
and causes a NULL deref in grub_normal_print_device_info().
I'm not sure if there's any implication with the IEEE 1275 platform.
Reference: http://git.savannah.gnu.org/cgit/grub.git/commit/?id=6afbe6063c95b827372f9ec310c9fc7461311eb1
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/commands/ls.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/grub-core/commands/ls.c b/grub-core/commands/ls.c
index 5b7491a..326d2d6 100644
--- a/grub-core/commands/ls.c
+++ b/grub-core/commands/ls.c
@@ -196,7 +196,7 @@ grub_ls_list_files (char *dirname, int longlist, int all, int human)
goto fail;
}
- if (! *path)
+ if (! *path && device_name)
{
if (grub_errno == GRUB_ERR_UNKNOWN_FS)
grub_errno = GRUB_ERR_NONE;
--
2.19.1

View File

@ -0,0 +1,39 @@
From c7b1dc3c5cbe4d6bf9af4736f3fc6d62405dad31 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Mon, 11 Jan 2021 17:30:42 +1100
Subject: [PATCH] script/execute: Avoid crash when using "$#" outside a
function scope
"$#" represents the number of arguments to a function. It is only
defined in a function scope, where "scope" is non-NULL. Currently,
if we attempt to evaluate "$#" outside a function scope, "scope" will
be NULL and we will crash with a NULL pointer dereference.
Do not attempt to count arguments for "$#" if "scope" is NULL. This
will result in "$#" being interpreted as an empty string if evaluated
outside a function scope.
Reference: http://git.savannah.gnu.org/cgit/grub.git/commit/?id=fe0586347ee46f927ae27bb9673532da9f5dead5
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/script/execute.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/grub-core/script/execute.c b/grub-core/script/execute.c
index b6e326c..4bf8d38 100644
--- a/grub-core/script/execute.c
+++ b/grub-core/script/execute.c
@@ -519,7 +519,7 @@ gettext_putvar (const char *str, grub_size_t len,
return 0;
/* Enough for any number. */
- if (len == 1 && str[0] == '#')
+ if (len == 1 && str[0] == '#' && scope != NULL)
{
grub_snprintf (*ptr, 30, "%u", scope->argv.argc);
*ptr += grub_strlen (*ptr);
--
2.19.1

View File

@ -0,0 +1,41 @@
From bebb524f8bd54ffe42074d825b8b98913356a670 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Fri, 22 Jan 2021 16:18:26 +1100
Subject: [PATCH] script/execute: Don't crash on a "for" loop with no items
The following crashes the parser:
for x in; do
0
done
This is because grub_script_arglist_to_argv() doesn't consider the
possibility that arglist is NULL. Catch that explicitly.
This avoids a NULL pointer dereference.
Reference: http://git.savannah.gnu.org/cgit/grub.git/commit/?id=0a05f88e2bb33ed2a0cfd93f481f471efb7791aa
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/script/execute.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/grub-core/script/execute.c b/grub-core/script/execute.c
index 4bf8d38..0c6dd9c 100644
--- a/grub-core/script/execute.c
+++ b/grub-core/script/execute.c
@@ -658,6 +658,9 @@ grub_script_arglist_to_argv (struct grub_script_arglist *arglist,
struct grub_script_arg *arg = 0;
struct grub_script_argv result = { 0, 0, 0 };
+ if (arglist == NULL)
+ return 1;
+
for (; arglist && arglist->arg; arglist = arglist->next)
{
if (grub_script_argv_next (&result))
--
2.19.1

View File

@ -0,0 +1,48 @@
From 4dee187a7b30a8a666adf01a56cebca1f78e15f0 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Wed, 13 Jan 2021 22:19:01 +1100
Subject: [PATCH] kern/misc: Always set *end in grub_strtoull()
Currently, if there is an error in grub_strtoull(), *end is not set.
This differs from the usual behavior of strtoull(), and also means that
some callers may use an uninitialized value for *end.
Set *end unconditionally.
Reference: http://git.savannah.gnu.org/cgit/grub.git/commit/?id=f41f0af48ab7f7c135aac17ac862c30bde0bbab7
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/kern/misc.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/grub-core/kern/misc.c b/grub-core/kern/misc.c
index dc5e10b..8f8a32d 100644
--- a/grub-core/kern/misc.c
+++ b/grub-core/kern/misc.c
@@ -466,6 +466,10 @@ grub_strtoull (const char * restrict str, const char ** const restrict end,
{
grub_error (GRUB_ERR_OUT_OF_RANGE,
N_("overflow is detected"));
+
+ if (end)
+ *end = (char *) str;
+
return ~0ULL;
}
@@ -476,6 +480,10 @@ grub_strtoull (const char * restrict str, const char ** const restrict end,
if (! found)
{
grub_errno = GRUB_ERR_BAD_NUMBER;
+
+ if (end)
+ *end = (char *) str;
+
return 0;
}
--
2.19.1

View File

@ -0,0 +1,54 @@
From 05aa64ac71242bff90a2356a319d6373b44d7d10 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Fri, 15 Jan 2021 12:57:04 +1100
Subject: [PATCH] video/readers/jpeg: Catch files with unsupported quantization
or Huffman tables
Our decoder only supports 2 quantization tables. If a file asks for
a quantization table with index > 1, reject it.
Similarly, our decoder only supports 4 Huffman tables. If a file asks
for a Huffman table with index > 3, reject it.
This fixes some out of bounds reads. It's not clear what degree of control
over subsequent execution could be gained by someone who can carefully
set up the contents of memory before loading an invalid JPEG file.
Reference: http://git.savannah.gnu.org/cgit/grub.git/commit/?id=693989598fd38c3c0b2a928f4f64865b5681762f
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/video/readers/jpeg.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/grub-core/video/readers/jpeg.c b/grub-core/video/readers/jpeg.c
index 0b6ce3c..23f919a 100644
--- a/grub-core/video/readers/jpeg.c
+++ b/grub-core/video/readers/jpeg.c
@@ -333,7 +333,11 @@ grub_jpeg_decode_sof (struct grub_jpeg_data *data)
else if (ss != JPEG_SAMPLING_1x1)
return grub_error (GRUB_ERR_BAD_FILE_TYPE,
"jpeg: sampling method not supported");
+
data->comp_index[id][0] = grub_jpeg_get_byte (data);
+ if (data->comp_index[id][0] > 1)
+ return grub_error (GRUB_ERR_BAD_FILE_TYPE,
+ "jpeg: too many quantization tables");
}
if (data->file->offset != next_marker)
@@ -602,6 +606,10 @@ grub_jpeg_decode_sos (struct grub_jpeg_data *data)
ht = grub_jpeg_get_byte (data);
data->comp_index[id][1] = (ht >> 4);
data->comp_index[id][2] = (ht & 0xF) + 2;
+
+ if ((data->comp_index[id][1] < 0) || (data->comp_index[id][1] > 3) ||
+ (data->comp_index[id][2] < 0) || (data->comp_index[id][2] > 3))
+ return grub_error (GRUB_ERR_BAD_FILE_TYPE, "jpeg: invalid hufftable index");
}
grub_jpeg_get_byte (data); /* Skip 3 unused bytes. */
--
2.19.1

View File

@ -0,0 +1,49 @@
From 420121392a223d772381d5e82a256dcc3a41f080 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Fri, 15 Jan 2021 13:29:53 +1100
Subject: [PATCH] video/readers/jpeg: Catch OOB reads/writes in
grub_jpeg_decode_du()
The key line is:
du[jpeg_zigzag_order[pos]] = val * (int) data->quan_table[qt][pos];
jpeg_zigzag_order is grub_uint8_t[64].
I don't understand JPEG decoders quite well enough to explain what's
going on here. However, I observe sometimes pos=64, which leads to an
OOB read of the jpeg_zigzag_order global then an OOB write to du.
That leads to various unpleasant memory corruption conditions.
Catch where pos >= ARRAY_SIZE(jpeg_zigzag_order) and bail.
Reference: http://git.savannah.gnu.org/cgit/grub.git/commit/?id=34b85a6e07014383ddcad09f99ff239ad752dd1a
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/video/readers/jpeg.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/grub-core/video/readers/jpeg.c b/grub-core/video/readers/jpeg.c
index 23f919a..e514812 100644
--- a/grub-core/video/readers/jpeg.c
+++ b/grub-core/video/readers/jpeg.c
@@ -526,6 +526,14 @@ grub_jpeg_decode_du (struct grub_jpeg_data *data, int id, jpeg_data_unit_t du)
val = grub_jpeg_get_number (data, num & 0xF);
num >>= 4;
pos += num;
+
+ if (pos >= ARRAY_SIZE (jpeg_zigzag_order))
+ {
+ grub_error (GRUB_ERR_BAD_FILE_TYPE,
+ "jpeg: invalid position in zigzag order!?");
+ return;
+ }
+
du[jpeg_zigzag_order[pos]] = val * (int) data->quan_table[qt][pos];
pos++;
}
--
2.19.1

View File

@ -0,0 +1,41 @@
From cd1d391aa0babd48c3ac2836fc841ce325c54f98 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Fri, 15 Jan 2021 14:06:46 +1100
Subject: [PATCH] video/readers/jpeg: Don't decode data before start of stream
When a start of stream marker is encountered, we call grub_jpeg_decode_sos()
which allocates space for a bitmap.
When a restart marker is encountered, we call grub_jpeg_decode_data() which
then fills in that bitmap.
If we get a restart marker before the start of stream marker, we will
attempt to write to a bitmap_ptr that hasn't been allocated. Catch this
and bail out. This fixes an attempt to write to NULL.
Reference: http://git.savannah.gnu.org/cgit/grub.git/commit/?id=8338a8238f08d9f3ae4c2ddfff0603eff80af9e2
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/video/readers/jpeg.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/grub-core/video/readers/jpeg.c b/grub-core/video/readers/jpeg.c
index e514812..e31602f 100644
--- a/grub-core/video/readers/jpeg.c
+++ b/grub-core/video/readers/jpeg.c
@@ -646,6 +646,10 @@ grub_jpeg_decode_data (struct grub_jpeg_data *data)
nr1 = (data->image_height + vb - 1) >> (3 + data->log_vs);
nc1 = (data->image_width + hb - 1) >> (3 + data->log_hs);
+ if (data->bitmap_ptr == NULL)
+ return grub_error(GRUB_ERR_BAD_FILE_TYPE,
+ "jpeg: attempted to decode data before start of stream");
+
for (; data->r1 < nr1 && (!data->dri || rst);
data->r1++, data->bitmap_ptr += (vb * data->image_width - hb * nc1) * 3)
for (c1 = 0; c1 < nc1 && (!data->dri || rst);
--
2.19.1

View File

@ -0,0 +1,53 @@
From 3f68d043b1624a320fdfdc39a064aabd06ff4a58 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Fri, 15 Jan 2021 20:03:20 +1100
Subject: [PATCH] term/gfxterm: Don't set up a font with glyphs that are too
big
Catch the case where we have a font so big that it causes the number of
rows or columns to be 0. Currently we continue and allocate a
virtual_screen.text_buffer of size 0. We then try to use that for glpyhs
and things go badly.
On the emu platform, malloc() may give us a valid pointer, in which case
we'll access heap memory which we shouldn't. Alternatively, it may give us
NULL, in which case we'll crash. For other platforms, if I understand
grub_memalign() correctly, we will receive a valid but small allocation
that we will very likely later overrun.
Prevent the creation of a virtual screen that isn't at least 40 cols
by 12 rows. This is arbitrary, but it seems that if your width or height
is half a standard 80x24 terminal, you're probably going to struggle to
read anything anyway.
Reference: http://git.savannah.gnu.org/cgit/grub.git/commit/?id=829329bddb2c3e623270cc634cc9ab32e6455fe7
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/term/gfxterm.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/grub-core/term/gfxterm.c b/grub-core/term/gfxterm.c
index af7c090..b40fcce 100644
--- a/grub-core/term/gfxterm.c
+++ b/grub-core/term/gfxterm.c
@@ -232,6 +232,15 @@ grub_virtual_screen_setup (unsigned int x, unsigned int y,
virtual_screen.columns = virtual_screen.width / virtual_screen.normal_char_width;
virtual_screen.rows = virtual_screen.height / virtual_screen.normal_char_height;
+ /*
+ * There must be a minimum number of rows and columns for the screen to
+ * make sense. Arbitrarily pick half of 80x24. If either dimensions is 0
+ * we would allocate 0 bytes for the text_buffer.
+ */
+ if (virtual_screen.columns < 40 || virtual_screen.rows < 12)
+ return grub_error (GRUB_ERR_BAD_FONT,
+ "font: glyphs too large to fit on screen");
+
/* Allocate memory for text buffer. */
virtual_screen.text_buffer =
(struct grub_colored_char *) grub_malloc (virtual_screen.columns
--
2.19.1

View File

@ -0,0 +1,48 @@
From 717b6b29d8b0bff9a1f89a3f602ece385c0e9d3d Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Mon, 18 Jan 2021 11:46:39 +1100
Subject: [PATCH] fs/fshelp: Catch impermissibly large block sizes in read
helper
A fuzzed HFS+ filesystem had log2blocksize = 22. This gave
log2blocksize + GRUB_DISK_SECTOR_BITS = 31. 1 << 31 = 0x80000000,
which is -1 as an int. This caused some wacky behavior later on in
the function, leading to out-of-bounds writes on the destination buffer.
Catch log2blocksize + GRUB_DISK_SECTOR_BITS >= 31. We could be stricter,
but this is the minimum that will prevent integer size weirdness.
Reference: http://git.savannah.gnu.org/cgit/grub.git/commit/?id=b5bc456f664bc301ab4cd5a17d3d23c6661c259e
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/fs/fshelp.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/grub-core/fs/fshelp.c b/grub-core/fs/fshelp.c
index 4c902ad..a2d0d29 100644
--- a/grub-core/fs/fshelp.c
+++ b/grub-core/fs/fshelp.c
@@ -362,6 +362,18 @@ grub_fshelp_read_file (grub_disk_t disk, grub_fshelp_node_t node,
grub_disk_addr_t i, blockcnt;
int blocksize = 1 << (log2blocksize + GRUB_DISK_SECTOR_BITS);
+ /*
+ * Catch blatantly invalid log2blocksize. We could be a lot stricter, but
+ * this is the most permissive we can be before we start to see integer
+ * overflow/underflow issues.
+ */
+ if (log2blocksize + GRUB_DISK_SECTOR_BITS >= 31)
+ {
+ grub_error (GRUB_ERR_OUT_OF_RANGE,
+ N_("blocksize too large"));
+ return -1;
+ }
+
if (pos > filesize)
{
grub_error (GRUB_ERR_OUT_OF_RANGE,
--
2.19.1

View File

@ -0,0 +1,34 @@
From cb045eb0b724ae94dca014ef83a6f0c3ae802d83 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Fri, 22 Jan 2021 18:13:56 +1100
Subject: [PATCH] fs/hfsplus: Don't fetch a key beyond the end of the node
Otherwise you get a wild pointer, leading to a bunch of invalid reads.
Check it falls inside the given node.
Reference: http://git.savannah.gnu.org/cgit/grub.git/commit/?id=58ea11d5b9ca0966bd9c68d8ba5240cf7dc3ba83
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/fs/hfsplus.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/grub-core/fs/hfsplus.c b/grub-core/fs/hfsplus.c
index 8fe7c12..1c7791b 100644
--- a/grub-core/fs/hfsplus.c
+++ b/grub-core/fs/hfsplus.c
@@ -635,6 +635,10 @@ grub_hfsplus_btree_search (struct grub_hfsplus_btree *btree,
pointer = ((char *) currkey
+ grub_be_to_cpu16 (currkey->keylen)
+ 2);
+
+ if ((char *) pointer > node + btree->nodesize - 2)
+ return grub_error (GRUB_ERR_BAD_FS, "HFS+ key beyond end of node");
+
currnode = grub_be_to_cpu32 (grub_get_unaligned32 (pointer));
match = 1;
}
--
2.19.1

View File

@ -0,0 +1,109 @@
From dbfe338e79d47fc535bd924660ae5bb0881716d3 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Tue, 2 Feb 2021 16:59:35 +1100
Subject: [PATCH] fs/hfsplus: Don't use uninitialized data on corrupt
filesystems
Valgrind identified the following use of uninitialized data:
==2782220== Conditional jump or move depends on uninitialised value(s)
==2782220== at 0x42B364: grub_hfsplus_btree_search (hfsplus.c:566)
==2782220== by 0x42B21D: grub_hfsplus_read_block (hfsplus.c:185)
==2782220== by 0x42A693: grub_fshelp_read_file (fshelp.c:386)
==2782220== by 0x42C598: grub_hfsplus_read_file (hfsplus.c:219)
==2782220== by 0x42C598: grub_hfsplus_mount (hfsplus.c:330)
==2782220== by 0x42B8C5: grub_hfsplus_dir (hfsplus.c:958)
==2782220== by 0x4C1AE6: grub_fs_probe (fs.c:73)
==2782220== by 0x407C94: grub_ls_list_files (ls.c:186)
==2782220== by 0x407C94: grub_cmd_ls (ls.c:284)
==2782220== by 0x4D7130: grub_extcmd_dispatcher (extcmd.c:55)
==2782220== by 0x4045A6: execute_command (grub-fstest.c:59)
==2782220== by 0x4045A6: fstest (grub-fstest.c:433)
==2782220== by 0x4045A6: main (grub-fstest.c:772)
==2782220== Uninitialised value was created by a heap allocation
==2782220== at 0x483C7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
==2782220== by 0x4C0305: grub_malloc (mm.c:42)
==2782220== by 0x42C21D: grub_hfsplus_mount (hfsplus.c:239)
==2782220== by 0x42B8C5: grub_hfsplus_dir (hfsplus.c:958)
==2782220== by 0x4C1AE6: grub_fs_probe (fs.c:73)
==2782220== by 0x407C94: grub_ls_list_files (ls.c:186)
==2782220== by 0x407C94: grub_cmd_ls (ls.c:284)
==2782220== by 0x4D7130: grub_extcmd_dispatcher (extcmd.c:55)
==2782220== by 0x4045A6: execute_command (grub-fstest.c:59)
==2782220== by 0x4045A6: fstest (grub-fstest.c:433)
==2782220== by 0x4045A6: main (grub-fstest.c:772)
This happens when the process of reading the catalog file goes sufficiently
wrong that there's an attempt to read the extent overflow file, which has
not yet been loaded. Keep track of when the extent overflow file is
fully loaded and refuse to use it before then.
The load valgrind doesn't like is btree->nodesize, and that's then used
to allocate a data structure. It looks like there are subsequently a lot
of reads based on that pointer so OOB reads are likely, and indeed crashes
(albeit difficult-to-replicate ones) have been observed in fuzzing.
Reference: http://git.savannah.gnu.org/cgit/grub.git/commit/?id=2ca0e5dbcdcb6fc93ccae39a0f39d0dba4a7ff20
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/fs/hfsplus.c | 14 ++++++++++++++
include/grub/hfsplus.h | 2 ++
2 files changed, 16 insertions(+)
diff --git a/grub-core/fs/hfsplus.c b/grub-core/fs/hfsplus.c
index 1c7791b..361e5be 100644
--- a/grub-core/fs/hfsplus.c
+++ b/grub-core/fs/hfsplus.c
@@ -177,6 +177,17 @@ grub_hfsplus_read_block (grub_fshelp_node_t node, grub_disk_addr_t fileblock)
break;
}
+ /*
+ * If the extent overflow tree isn't ready yet, we can't look
+ * in it. This can happen where the catalog file is corrupted.
+ */
+ if (!node->data->extoverflow_tree_ready)
+ {
+ grub_error (GRUB_ERR_BAD_FS,
+ "attempted to read extent overflow tree before loading");
+ break;
+ }
+
/* Set up the key to look for in the extent overflow file. */
extoverflow.extkey.fileid = node->fileid;
extoverflow.extkey.type = 0;
@@ -241,6 +252,7 @@ grub_hfsplus_mount (grub_disk_t disk)
return 0;
data->disk = disk;
+ data->extoverflow_tree_ready = 0;
/* Read the bootblock. */
grub_disk_read (disk, GRUB_HFSPLUS_SBLOCK, 0, sizeof (volheader),
@@ -357,6 +369,8 @@ grub_hfsplus_mount (grub_disk_t disk)
if (data->extoverflow_tree.nodesize < 2)
goto fail;
+ data->extoverflow_tree_ready = 1;
+
if (grub_hfsplus_read_file (&data->attr_tree.file, 0, 0,
sizeof (struct grub_hfsplus_btnode),
sizeof (header), (char *) &header) <= 0)
diff --git a/include/grub/hfsplus.h b/include/grub/hfsplus.h
index 117740a..e14dd31 100644
--- a/include/grub/hfsplus.h
+++ b/include/grub/hfsplus.h
@@ -113,6 +113,8 @@ struct grub_hfsplus_data
struct grub_hfsplus_btree extoverflow_tree;
struct grub_hfsplus_btree attr_tree;
+ int extoverflow_tree_ready;
+
struct grub_hfsplus_file dirroot;
struct grub_hfsplus_file opened_file;
--
2.19.1

View File

@ -0,0 +1,48 @@
From 0cb62a411ee329bc3f25e46303c3e458b905bb34 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Mon, 18 Jan 2021 12:19:07 +1100
Subject: [PATCH] fs/hfs: Disable under lockdown
HFS has issues such as infinite mutual recursion that are simply too
complex to fix for such a legacy format. So simply do not permit
it to be loaded under lockdown.
Reference: http://git.savannah.gnu.org/cgit/grub.git/commit/?id=1c15848838d924552611247110723e2a1c17a5a1
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/fs/hfs.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/grub-core/fs/hfs.c b/grub-core/fs/hfs.c
index 3fe842b..9a5b7bb 100644
--- a/grub-core/fs/hfs.c
+++ b/grub-core/fs/hfs.c
@@ -30,6 +30,7 @@
#include <grub/hfs.h>
#include <grub/i18n.h>
#include <grub/fshelp.h>
+#include <grub/lockdown.h>
GRUB_MOD_LICENSE ("GPLv3+");
@@ -1433,11 +1434,13 @@ static struct grub_fs grub_hfs_fs =
GRUB_MOD_INIT(hfs)
{
- grub_fs_register (&grub_hfs_fs);
+ if (!grub_is_lockdown ())
+ grub_fs_register (&grub_hfs_fs);
my_mod = mod;
}
GRUB_MOD_FINI(hfs)
{
- grub_fs_unregister (&grub_hfs_fs);
+ if (!grub_is_lockdown())
+ grub_fs_unregister (&grub_hfs_fs);
}
--
2.19.1

View File

@ -0,0 +1,51 @@
From 087dad12b18f238b360aade771d34f4e8d50a8b9 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Mon, 18 Jan 2021 14:34:58 +1100
Subject: [PATCH] fs/sfs: Fix over-read of root object name
There's a read of the name of the root object that assumes that the name
is nul-terminated within the root block. This isn't guaranteed - it seems
SFS would require you to read multiple blocks to get a full name in general,
but maybe that doesn't apply to the root object.
Either way, figure out how much space is left in the root block and don't
over-read it. This fixes some OOB reads.
Reference: http://git.savannah.gnu.org/cgit/grub.git/commit/?id=8d3ae59dee2930d640add3bba983006e1f5dd1b6
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/fs/sfs.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/grub-core/fs/sfs.c b/grub-core/fs/sfs.c
index de2b107..983e880 100644
--- a/grub-core/fs/sfs.c
+++ b/grub-core/fs/sfs.c
@@ -373,6 +373,7 @@ grub_sfs_mount (grub_disk_t disk)
struct grub_sfs_objc *rootobjc;
char *rootobjc_data = 0;
grub_uint32_t blk;
+ unsigned int max_len;
data = grub_malloc (sizeof (*data));
if (!data)
@@ -421,7 +422,13 @@ grub_sfs_mount (grub_disk_t disk)
data->diropen.data = data;
data->diropen.cache = 0;
data->disk = disk;
- data->label = grub_strdup ((char *) (rootobjc->objects[0].filename));
+
+ /* We only read 1 block of data, so truncate the name if needed. */
+ max_len = ((GRUB_DISK_SECTOR_SIZE << data->log_blocksize)
+ - 24 /* offsetof (struct grub_sfs_objc, objects) */
+ - 25); /* offsetof (struct grub_sfs_obj, filename) */
+ data->label = grub_zalloc (max_len + 1);
+ grub_strncpy (data->label, (char *) rootobjc->objects[0].filename, max_len);
grub_free (rootobjc_data);
return data;
--
2.19.1

View File

@ -0,0 +1,35 @@
From fb52b550be82812b6e9a4eeb0bc80bf1ae67de0b Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Mon, 18 Jan 2021 14:51:11 +1100
Subject: [PATCH] fs/jfs: Do not move to leaf level if name length is negative
Fuzzing JFS revealed crashes where a negative number would be passed
to le_to_cpu16_copy(). There it would be cast to a large positive number
and the copy would read and write off the end of the respective buffers.
Catch this at the top as well as the bottom of the loop.
Reference: http://git.savannah.gnu.org/cgit/grub.git/commit/?id=ffd5a46f68710e2781899d0be4d701429a5a817d
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/fs/jfs.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/grub-core/fs/jfs.c b/grub-core/fs/jfs.c
index d5a6d65..e5bbda6 100644
--- a/grub-core/fs/jfs.c
+++ b/grub-core/fs/jfs.c
@@ -567,7 +567,7 @@ grub_jfs_getent (struct grub_jfs_diropen *diro)
/* Move down to the leaf level. */
nextent = leaf->next;
- if (leaf->next != 255)
+ if (leaf->next != 255 && len > 0)
do
{
next_leaf = &diro->next_leaf[nextent];
--
2.19.1

View File

@ -0,0 +1,63 @@
From 53d8b876fbe2b507845e81a7758a8bbe5f1d4f2d Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Mon, 18 Jan 2021 14:57:17 +1100
Subject: [PATCH] fs/jfs: Limit the extents that getblk() can consider
getblk() implicitly trusts that treehead->count is an accurate count of
the number of extents. However, that value is read from disk and is not
trustworthy, leading to OOB reads and crashes. I am not sure to what
extent the data read from OOB can influence subsequent program execution.
Require callers to pass in the maximum number of extents for which
they have storage.
Reference: http://git.savannah.gnu.org/cgit/grub.git/commit/?id=bd0cf8148ccf721f6e39ffbd70f8abad0c8897f0
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/fs/jfs.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/grub-core/fs/jfs.c b/grub-core/fs/jfs.c
index e5bbda6..804c42d 100644
--- a/grub-core/fs/jfs.c
+++ b/grub-core/fs/jfs.c
@@ -261,13 +261,15 @@ static grub_err_t grub_jfs_lookup_symlink (struct grub_jfs_data *data, grub_uint
static grub_int64_t
getblk (struct grub_jfs_treehead *treehead,
struct grub_jfs_tree_extent *extents,
+ int max_extents,
struct grub_jfs_data *data,
grub_uint64_t blk)
{
int found = -1;
int i;
- for (i = 0; i < grub_le_to_cpu16 (treehead->count) - 2; i++)
+ for (i = 0; i < grub_le_to_cpu16 (treehead->count) - 2 &&
+ i < max_extents; i++)
{
if (treehead->flags & GRUB_JFS_TREE_LEAF)
{
@@ -302,7 +304,7 @@ getblk (struct grub_jfs_treehead *treehead,
<< (grub_le_to_cpu16 (data->sblock.log2_blksz)
- GRUB_DISK_SECTOR_BITS), 0,
sizeof (*tree), (char *) tree))
- ret = getblk (&tree->treehead, &tree->extents[0], data, blk);
+ ret = getblk (&tree->treehead, &tree->extents[0], 254, data, blk);
grub_free (tree);
return ret;
}
@@ -316,7 +318,7 @@ static grub_int64_t
grub_jfs_blkno (struct grub_jfs_data *data, struct grub_jfs_inode *inode,
grub_uint64_t blk)
{
- return getblk (&inode->file.tree, &inode->file.extents[0], data, blk);
+ return getblk (&inode->file.tree, &inode->file.extents[0], 16, data, blk);
}
--
2.19.1

View File

@ -0,0 +1,47 @@
From 1311dfb93e144af93d6c91949101a802d46a510f Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Mon, 18 Jan 2021 15:47:24 +1100
Subject: [PATCH] fs/jfs: Catch infinite recursion
It's possible with a fuzzed filesystem for JFS to keep getblk()-ing
the same data over and over again, leading to stack exhaustion.
Check if we'd be calling the function with exactly the same data as
was passed in, and if so abort.
I'm not sure what the performance impact of this is and am open to
better ideas.
Reference: http://git.savannah.gnu.org/cgit/grub.git/commit/?id=223120dd83745126cb232a0248c9a8901d7e350d
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/fs/jfs.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/grub-core/fs/jfs.c b/grub-core/fs/jfs.c
index 804c42d..6f7c439 100644
--- a/grub-core/fs/jfs.c
+++ b/grub-core/fs/jfs.c
@@ -304,7 +304,16 @@ getblk (struct grub_jfs_treehead *treehead,
<< (grub_le_to_cpu16 (data->sblock.log2_blksz)
- GRUB_DISK_SECTOR_BITS), 0,
sizeof (*tree), (char *) tree))
- ret = getblk (&tree->treehead, &tree->extents[0], 254, data, blk);
+ {
+ if (grub_memcmp (&tree->treehead, treehead, sizeof (struct grub_jfs_treehead)) ||
+ grub_memcmp (&tree->extents, extents, 254 * sizeof (struct grub_jfs_tree_extent)))
+ ret = getblk (&tree->treehead, &tree->extents[0], 254, data, blk);
+ else
+ {
+ grub_error (GRUB_ERR_BAD_FS, "jfs: infinite recursion detected");
+ ret = -1;
+ }
+ }
grub_free (tree);
return ret;
}
--
2.19.1

View File

@ -0,0 +1,47 @@
From 054375c8ae2e78a53b8a098265c18515770cf599 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Mon, 18 Jan 2021 16:49:09 +1100
Subject: [PATCH] fs/nilfs2: Reject too-large keys
NILFS2 has up to 7 keys, per the data structure. Do not permit array
indices in excess of that.
This catches some OOB reads. I don't know how controllable the invalidly
read data is or if that could be used later in the program.
Reference: http://git.savannah.gnu.org/cgit/grub.git/commit/?id=20ab8cb44bc140a1dedda82a3fccdd45e9bc6929
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/fs/nilfs2.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/grub-core/fs/nilfs2.c b/grub-core/fs/nilfs2.c
index 7ed148d..fee2242 100644
--- a/grub-core/fs/nilfs2.c
+++ b/grub-core/fs/nilfs2.c
@@ -569,6 +569,11 @@ grub_nilfs2_btree_lookup (struct grub_nilfs2_data *data,
static inline grub_uint64_t
grub_nilfs2_direct_lookup (struct grub_nilfs2_inode *inode, grub_uint64_t key)
{
+ if (1 + key > 6)
+ {
+ grub_error (GRUB_ERR_BAD_FS, "key is too large");
+ return 0xffffffffffffffff;
+ }
return grub_le_to_cpu64 (inode->i_bmap[1 + key]);
}
@@ -584,7 +589,7 @@ grub_nilfs2_bmap_lookup (struct grub_nilfs2_data *data,
{
grub_uint64_t ptr;
ptr = grub_nilfs2_direct_lookup (inode, key);
- if (need_translate)
+ if (ptr != ((grub_uint64_t) 0xffffffffffffffff) && need_translate)
ptr = grub_nilfs2_dat_translate (data, ptr);
return ptr;
}
--
2.19.1

View File

@ -0,0 +1,101 @@
From 1e3762857742b41d0752a9dd52513481bc4ecaf0 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Mon, 18 Jan 2021 16:49:44 +1100
Subject: [PATCH] fs/nilfs2: Don't search children if provided number is too
large
NILFS2 reads the number of children a node has from the node. Unfortunately,
that's not trustworthy. Check if it's beyond what the filesystem permits and
reject it if so.
This blocks some OOB reads. I'm not sure how controllable the read is and what
could be done with invalidly read data later on.
Reference: http://git.savannah.gnu.org/cgit/grub.git/commit/?id=37c0eb05cdcc64c28d31c4ebd300f14d5239d05e
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/fs/nilfs2.c | 38 +++++++++++++++++++++++---------------
1 file changed, 23 insertions(+), 15 deletions(-)
diff --git a/grub-core/fs/nilfs2.c b/grub-core/fs/nilfs2.c
index fee2242..43ac1ad 100644
--- a/grub-core/fs/nilfs2.c
+++ b/grub-core/fs/nilfs2.c
@@ -416,14 +416,34 @@ grub_nilfs2_btree_node_get_key (struct grub_nilfs2_btree_node *node,
}
static inline int
-grub_nilfs2_btree_node_lookup (struct grub_nilfs2_btree_node *node,
+grub_nilfs2_btree_node_nchildren_max (struct grub_nilfs2_data *data,
+ struct grub_nilfs2_btree_node *node)
+{
+ int node_children_max = ((NILFS2_BLOCK_SIZE (data) -
+ sizeof (struct grub_nilfs2_btree_node) -
+ NILFS_BTREE_NODE_EXTRA_PAD_SIZE) /
+ (sizeof (grub_uint64_t) + sizeof (grub_uint64_t)));
+
+ return (node->bn_flags & NILFS_BTREE_NODE_ROOT) ? 3 : node_children_max;
+}
+
+static inline int
+grub_nilfs2_btree_node_lookup (struct grub_nilfs2_data *data,
+ struct grub_nilfs2_btree_node *node,
grub_uint64_t key, int *indexp)
{
grub_uint64_t nkey;
int index, low, high, s;
low = 0;
+
high = grub_le_to_cpu16 (node->bn_nchildren) - 1;
+ if (high >= grub_nilfs2_btree_node_nchildren_max (data, node))
+ {
+ grub_error (GRUB_ERR_BAD_FS, "too many children");
+ return 0;
+ }
+
index = 0;
s = 0;
while (low <= high)
@@ -459,18 +479,6 @@ grub_nilfs2_btree_node_lookup (struct grub_nilfs2_btree_node *node,
return s == 0;
}
-static inline int
-grub_nilfs2_btree_node_nchildren_max (struct grub_nilfs2_data *data,
- struct grub_nilfs2_btree_node *node)
-{
- int node_children_max = ((NILFS2_BLOCK_SIZE (data) -
- sizeof (struct grub_nilfs2_btree_node) -
- NILFS_BTREE_NODE_EXTRA_PAD_SIZE) /
- (sizeof (grub_uint64_t) + sizeof (grub_uint64_t)));
-
- return (node->bn_flags & NILFS_BTREE_NODE_ROOT) ? 3 : node_children_max;
-}
-
static inline grub_uint64_t *
grub_nilfs2_btree_node_dptrs (struct grub_nilfs2_data *data,
struct grub_nilfs2_btree_node *node)
@@ -517,7 +525,7 @@ grub_nilfs2_btree_lookup (struct grub_nilfs2_data *data,
node = grub_nilfs2_btree_get_root (inode);
level = grub_nilfs2_btree_get_level (node);
- found = grub_nilfs2_btree_node_lookup (node, key, &index);
+ found = grub_nilfs2_btree_node_lookup (data, node, key, &index);
ptr = grub_nilfs2_btree_node_get_ptr (data, node, index);
if (need_translate)
ptr = grub_nilfs2_dat_translate (data, ptr);
@@ -538,7 +546,7 @@ grub_nilfs2_btree_lookup (struct grub_nilfs2_data *data,
}
if (!found)
- found = grub_nilfs2_btree_node_lookup (node, key, &index);
+ found = grub_nilfs2_btree_node_lookup (data, node, key, &index);
else
index = 0;
--
2.19.1

View File

@ -0,0 +1,69 @@
From 5d69fb2f9cee027c76ff179478ca3ec7069ac7ce Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Mon, 18 Jan 2021 17:06:19 +1100
Subject: [PATCH] fs/nilfs2: Properly bail on errors in
grub_nilfs2_btree_node_lookup()
We just introduced an error return in grub_nilfs2_btree_node_lookup().
Make sure the callers catch it.
At the same time, make sure that grub_nilfs2_btree_node_lookup() always
inits the index pointer passed to it.
Reference: http://git.savannah.gnu.org/cgit/grub.git/commit/?id=ca5d9ac206043b1fb4cb06259272fb1c5946bb6d
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/fs/nilfs2.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/grub-core/fs/nilfs2.c b/grub-core/fs/nilfs2.c
index 43ac1ad..aaba002 100644
--- a/grub-core/fs/nilfs2.c
+++ b/grub-core/fs/nilfs2.c
@@ -433,7 +433,7 @@ grub_nilfs2_btree_node_lookup (struct grub_nilfs2_data *data,
grub_uint64_t key, int *indexp)
{
grub_uint64_t nkey;
- int index, low, high, s;
+ int index = 0, low, high, s;
low = 0;
@@ -441,10 +441,10 @@ grub_nilfs2_btree_node_lookup (struct grub_nilfs2_data *data,
if (high >= grub_nilfs2_btree_node_nchildren_max (data, node))
{
grub_error (GRUB_ERR_BAD_FS, "too many children");
+ *indexp = index;
return 0;
}
- index = 0;
s = 0;
while (low <= high)
{
@@ -526,6 +526,10 @@ grub_nilfs2_btree_lookup (struct grub_nilfs2_data *data,
level = grub_nilfs2_btree_get_level (node);
found = grub_nilfs2_btree_node_lookup (data, node, key, &index);
+
+ if (grub_errno != GRUB_ERR_NONE)
+ goto fail;
+
ptr = grub_nilfs2_btree_node_get_ptr (data, node, index);
if (need_translate)
ptr = grub_nilfs2_dat_translate (data, ptr);
@@ -550,7 +554,8 @@ grub_nilfs2_btree_lookup (struct grub_nilfs2_data *data,
else
index = 0;
- if (index < grub_nilfs2_btree_node_nchildren_max (data, node))
+ if (index < grub_nilfs2_btree_node_nchildren_max (data, node) &&
+ grub_errno == GRUB_ERR_NONE)
{
ptr = grub_nilfs2_btree_node_get_ptr (data, node, index);
if (need_translate)
--
2.19.1

View File

@ -0,0 +1,68 @@
From 4b1839b9d9220161a20041722458b39b269fb70d Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Wed, 13 Jan 2021 20:59:09 +1100
Subject: [PATCH] io/gzio: Bail if gzio->tl/td is NULL
This is an ugly fix that doesn't address why gzio->tl comes to be NULL.
However, it seems to be sufficient to patch up a bunch of NULL derefs.
It would be good to revisit this in future and see if we can have
a cleaner solution that addresses some of the causes of the unexpected
NULL pointers.
Reference: http://git.savannah.gnu.org/cgit/grub.git/commit/?id=3334a5e6c86f10e715cca3bf66ce0fc2f164b61b
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/io/gzio.c | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/grub-core/io/gzio.c b/grub-core/io/gzio.c
index 43d98a7..4a8eaea 100644
--- a/grub-core/io/gzio.c
+++ b/grub-core/io/gzio.c
@@ -669,6 +669,13 @@ inflate_codes_in_window (grub_gzio_t gzio)
{
if (! gzio->code_state)
{
+
+ if (gzio->tl == NULL)
+ {
+ grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, "NULL gzio->tl");
+ return 1;
+ }
+
NEEDBITS ((unsigned) gzio->bl);
if ((e = (t = gzio->tl + ((unsigned) b & ml))->e) > 16)
do
@@ -707,6 +714,12 @@ inflate_codes_in_window (grub_gzio_t gzio)
n = t->v.n + ((unsigned) b & mask_bits[e]);
DUMPBITS (e);
+ if (gzio->td == NULL)
+ {
+ grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, "NULL gzio->td");
+ return 1;
+ }
+
/* decode distance of block to copy */
NEEDBITS ((unsigned) gzio->bd);
if ((e = (t = gzio->td + ((unsigned) b & md))->e) > 16)
@@ -917,6 +930,13 @@ init_dynamic_block (grub_gzio_t gzio)
n = nl + nd;
m = mask_bits[gzio->bl];
i = l = 0;
+
+ if (gzio->tl == NULL)
+ {
+ grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, "NULL gzio->tl");
+ return;
+ }
+
while ((unsigned) i < n)
{
NEEDBITS ((unsigned) gzio->bl);
--
2.19.1

View File

@ -0,0 +1,68 @@
From 00c2eb1b68e59d50f8bbd5659d9c4b3bd8fc899a Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Thu, 21 Jan 2021 00:05:58 +1100
Subject: [PATCH] io/gzio: Add init_dynamic_block() clean up if unpacking codes
fails
init_dynamic_block() didn't clean up gzio->tl and td in some error
paths. This left td pointing to part of tl. Then in grub_gzio_close(),
when tl was freed the storage for td would also be freed. The code then
attempts to free td explicitly, performing a UAF and then a double free.
Explicitly clean up tl and td in the error paths.
Reference: http://git.savannah.gnu.org/cgit/grub.git/commit/?id=18490336d91da2b532277cba56473bfed1376fc4
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/io/gzio.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/grub-core/io/gzio.c b/grub-core/io/gzio.c
index 4a8eaea..d38b43f 100644
--- a/grub-core/io/gzio.c
+++ b/grub-core/io/gzio.c
@@ -953,7 +953,7 @@ init_dynamic_block (grub_gzio_t gzio)
if ((unsigned) i + j > n)
{
grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, "too many codes found");
- return;
+ goto fail;
}
while (j--)
ll[i++] = l;
@@ -966,7 +966,7 @@ init_dynamic_block (grub_gzio_t gzio)
if ((unsigned) i + j > n)
{
grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, "too many codes found");
- return;
+ goto fail;
}
while (j--)
ll[i++] = 0;
@@ -981,7 +981,7 @@ init_dynamic_block (grub_gzio_t gzio)
if ((unsigned) i + j > n)
{
grub_error (GRUB_ERR_BAD_COMPRESSED_DATA, "too many codes found");
- return;
+ goto fail;
}
while (j--)
ll[i++] = 0;
@@ -1019,6 +1019,12 @@ init_dynamic_block (grub_gzio_t gzio)
/* indicate we're now working on a block */
gzio->code_state = 0;
gzio->block_len++;
+ return;
+
+fail:
+ huft_free (gzio->tl);
+ gzio->td = NULL;
+ gzio->tl = NULL;
}
--
2.19.1

View File

@ -0,0 +1,58 @@
From 5c1220e03508fe8155d2c963eb38fe733bc48e40 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Thu, 21 Jan 2021 12:20:49 +1100
Subject: [PATCH] io/gzio: Catch missing values in huft_build() and bail
In huft_build(), "v" is a table of values in order of bit length.
The code later (when setting up table entries in "r") assumes that all
elements of this array corresponding to a code are initialized and less
than N_MAX. However, it doesn't enforce this.
With sufficiently manipulated inputs (e.g. from fuzzing), there can be
elements of "v" that are not filled. Therefore a lookup into "e" or "d"
will use an uninitialized value. This can lead to an invalid/OOB read on
those values, often leading to a crash.
Reference: http://git.savannah.gnu.org/cgit/grub.git/commit/?id=4e76b08f7171a8603d74fcafb27409a91f578647
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/io/gzio.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/grub-core/io/gzio.c b/grub-core/io/gzio.c
index d38b43f..0b95cf3 100644
--- a/grub-core/io/gzio.c
+++ b/grub-core/io/gzio.c
@@ -507,6 +507,7 @@ huft_build (unsigned *b, /* code lengths in bits (all assumed <= BMAX) */
}
/* Make a table of values in order of bit lengths */
+ grub_memset (v, N_MAX, ARRAY_SIZE (v));
p = b;
i = 0;
do
@@ -588,11 +589,18 @@ huft_build (unsigned *b, /* code lengths in bits (all assumed <= BMAX) */
r.v.n = (ush) (*p); /* simple code is just the value */
p++; /* one compiler does not like *p++ */
}
- else
+ else if (*p < N_MAX)
{
r.e = (uch) e[*p - s]; /* non-simple--look up in lists */
r.v.n = d[*p++ - s];
}
+ else
+ {
+ /* Detected an uninitialised value, abort. */
+ if (h)
+ huft_free (u[0]);
+ return 2;
+ }
/* fill code-like entries with r */
f = 1 << (k - w);
--
2.19.1

View File

@ -0,0 +1,43 @@
From 1d80defcd0db38752fbe94a53ea41c27c1117c80 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Thu, 21 Jan 2021 12:22:28 +1100
Subject: [PATCH] io/gzio: Zero gzio->tl/td in init_dynamic_block() if
huft_build() fails
If huft_build() fails, gzio->tl or gzio->td could contain pointers that
are no longer valid. Zero them out.
This prevents a double free when grub_gzio_close() comes through and
attempts to free them again.
Reference: http://git.savannah.gnu.org/cgit/grub.git/commit/?id=b5a2b59cc5b8f5ee7ba3b951e7693e402d5b3a6f
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/io/gzio.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/grub-core/io/gzio.c b/grub-core/io/gzio.c
index 0b95cf3..df8cf66 100644
--- a/grub-core/io/gzio.c
+++ b/grub-core/io/gzio.c
@@ -1010,6 +1010,7 @@ init_dynamic_block (grub_gzio_t gzio)
gzio->bl = lbits;
if (huft_build (ll, nl, 257, cplens, cplext, &gzio->tl, &gzio->bl) != 0)
{
+ gzio->tl = 0;
grub_error (GRUB_ERR_BAD_COMPRESSED_DATA,
"failed in building a Huffman code table");
return;
@@ -1019,6 +1020,7 @@ init_dynamic_block (grub_gzio_t gzio)
{
huft_free (gzio->tl);
gzio->tl = 0;
+ gzio->td = 0;
grub_error (GRUB_ERR_BAD_COMPRESSED_DATA,
"failed in building a Huffman code table");
return;
--
2.19.1

View File

@ -0,0 +1,50 @@
From 9251d03c58041e300f935379e9dd81375106a3ac Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Thu, 21 Jan 2021 17:59:14 +1100
Subject: [PATCH] disk/lvm: Don't go beyond the end of the data we read from
disk
We unconditionally trusted offset_xl from the LVM label header, even if
it told us that the PV header/disk locations were way off past the end
of the data we read from disk.
Require that the offset be sane, fixing an OOB read and crash.
Fixes: CID 314367, CID 314371
Reference: http://git.savannah.gnu.org/cgit/grub.git/commit/?id=a8cc95de74ccc3ad090e8062ac335c844f13c9f4
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/disk/lvm.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c
index 9f5630c..25e6c70 100644
--- a/grub-core/disk/lvm.c
+++ b/grub-core/disk/lvm.c
@@ -142,6 +142,20 @@ grub_lvm_detect (grub_disk_t disk,
goto fail;
}
+ /*
+ * We read a grub_lvm_pv_header and then 2 grub_lvm_disk_locns that
+ * immediately follow the PV header. Make sure we have space for both.
+ */
+ if (grub_le_to_cpu32 (lh->offset_xl) >=
+ GRUB_LVM_LABEL_SIZE - sizeof (struct grub_lvm_pv_header) -
+ 2 * sizeof (struct grub_lvm_disk_locn))
+ {
+#ifdef GRUB_UTIL
+ grub_util_info ("LVM PV header/disk locations are beyond the end of the block");
+#endif
+ goto fail;
+ }
+
pvh = (struct grub_lvm_pv_header *) (buf + grub_le_to_cpu32(lh->offset_xl));
for (i = 0, j = 0; i < GRUB_LVM_ID_LEN; i++)
--
2.19.1

View File

@ -0,0 +1,44 @@
From f702b93b2a023c941a49d6d3e18915fdd6c14c89 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Thu, 21 Jan 2021 18:19:51 +1100
Subject: [PATCH] disk/lvm: Don't blast past the end of the circular metadata
buffer
This catches at least some OOB reads, and it's possible I suppose that
if 2 * mda_size is less than GRUB_LVM_MDA_HEADER_SIZE it might catch some
OOB writes too (although that hasn't showed up as a crash in fuzzing yet).
It's a bit ugly and I'd appreciate better suggestions.
Reference: http://git.savannah.gnu.org/cgit/grub.git/commit/?id=27a79bf38e6d050e497eb96a3fdddce43af25577
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/disk/lvm.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c
index 25e6c70..f25521a 100644
--- a/grub-core/disk/lvm.c
+++ b/grub-core/disk/lvm.c
@@ -215,6 +215,16 @@ grub_lvm_detect (grub_disk_t disk,
if (grub_le_to_cpu64 (rlocn->offset) + grub_le_to_cpu64 (rlocn->size) >
grub_le_to_cpu64 (mdah->size))
{
+ if (2 * mda_size < GRUB_LVM_MDA_HEADER_SIZE ||
+ (grub_le_to_cpu64 (rlocn->offset) + grub_le_to_cpu64 (rlocn->size) -
+ grub_le_to_cpu64 (mdah->size) > mda_size - GRUB_LVM_MDA_HEADER_SIZE))
+ {
+#ifdef GRUB_UTIL
+ grub_util_info ("cannot copy metadata wrap in circular buffer");
+#endif
+ goto fail2;
+ }
+
/* Metadata is circular. Copy the wrap in place. */
grub_memcpy (metadatabuf + mda_size,
metadatabuf + GRUB_LVM_MDA_HEADER_SIZE,
--
2.19.1

View File

@ -0,0 +1,36 @@
From c8ca81d1cd6f486b028c34533c89b36f250870d4 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Thu, 21 Jan 2021 18:54:29 +1100
Subject: [PATCH] disk/lvm: Bail on missing PV list
There's an if block for the presence of "physical_volumes {", but if
that block is absent, then p remains NULL and a NULL-deref will result
when looking for logical volumes.
It doesn't seem like LVM makes sense without physical volumes, so error
out rather than crashing.
Reference: http://git.savannah.gnu.org/cgit/grub.git/commit/?id=2958695c4cdc785de6ed708709af071a2d20afef
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/disk/lvm.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c
index f25521a..944c398 100644
--- a/grub-core/disk/lvm.c
+++ b/grub-core/disk/lvm.c
@@ -371,6 +371,8 @@ grub_lvm_detect (grub_disk_t disk,
goto fail4;
}
}
+ else
+ goto fail4;
p = grub_strstr (p, "logical_volumes {");
if (p)
--
2.19.1

View File

@ -0,0 +1,84 @@
From e9b6e755fd0f4fcfac36c149d2c74cc2d483d65a Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Thu, 21 Jan 2021 18:35:22 +1100
Subject: [PATCH] disk/lvm: Do not crash if an expected string is not found
Clean up a bunch of cases where we could have strstr() fail and lead to
us dereferencing NULL.
We'll still leak memory in some cases (loops don't clean up allocations
from earlier iterations if a later iteration fails) but at least we're
not crashing.
Reference: http://git.savannah.gnu.org/cgit/grub.git/commit/?id=db29073fc7aec71a40dabfc722a96ea9f3280907
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/disk/lvm.c | 22 +++++++++++++++++-----
1 file changed, 17 insertions(+), 5 deletions(-)
diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c
index 944c398..85ee89c 100644
--- a/grub-core/disk/lvm.c
+++ b/grub-core/disk/lvm.c
@@ -540,7 +540,16 @@ grub_lvm_detect (grub_disk_t disk,
}
if (seg->node_count != 1)
- seg->stripe_size = grub_lvm_getvalue (&p, "stripe_size = ");
+ {
+ seg->stripe_size = grub_lvm_getvalue (&p, "stripe_size = ");
+ if (p == NULL)
+ {
+#ifdef GRUB_UTIL
+ grub_util_info ("unknown stripe_size");
+#endif
+ goto lvs_segment_fail;
+ }
+ }
seg->nodes = grub_calloc (seg->node_count,
sizeof (*stripe));
@@ -560,7 +569,7 @@ grub_lvm_detect (grub_disk_t disk,
{
p = grub_strchr (p, '"');
if (p == NULL)
- continue;
+ goto lvs_segment_fail2;
q = ++p;
while (*q != '"')
q++;
@@ -579,7 +588,10 @@ grub_lvm_detect (grub_disk_t disk,
stripe->start = grub_lvm_getvalue (&p, ",")
* vg->extent_size;
if (p == NULL)
- continue;
+ {
+ grub_free (stripe->name);
+ goto lvs_segment_fail2;
+ }
stripe++;
}
@@ -616,7 +628,7 @@ grub_lvm_detect (grub_disk_t disk,
p = grub_strchr (p, '"');
if (p == NULL)
- continue;
+ goto lvs_segment_fail2;
q = ++p;
while (*q != '"')
q++;
@@ -704,7 +716,7 @@ grub_lvm_detect (grub_disk_t disk,
p = p ? grub_strchr (p + 1, '"') : 0;
p = p ? grub_strchr (p + 1, '"') : 0;
if (p == NULL)
- continue;
+ goto lvs_segment_fail2;
q = ++p;
while (*q != '"')
q++;
--
2.19.1

View File

@ -0,0 +1,286 @@
From cd73fa65a8fc466950d49ee854f1b986730d94e7 Mon Sep 17 00:00:00 2001
From: Michael Chang <mchang@suse.com>
Date: Thu, 19 Mar 2020 13:56:13 +0800
Subject: [PATCH] lvm: Add LVM cache logical volume handling
The LVM cache logical volume is the logical volume consisting of the original
and the cache pool logical volume. The original is usually on a larger and
slower storage device while the cache pool is on a smaller and faster one. The
performance of the original volume can be improved by storing the frequently
used data on the cache pool to utilize the greater performance of faster
device.
The default cache mode "writethrough" ensures that any data written will be
stored both in the cache and on the origin LV, therefore grub can be straight
to read the original lv as no data loss is guarenteed.
The second cache mode is "writeback", which delays writing from the cache pool
back to the origin LV to have increased performance. The drawback is potential
data loss if losing the associated cache device.
During the boot time grub reads the LVM offline i.e. LVM volumes are not
activated and mounted, hence it should be fine to read directly from original
lv since all cached data should have been flushed back in the process of taking
it offline.
It is also not much helpful to the situation by adding fsync calls to the
install code. The fsync did not force to write back dirty cache to the original
device and rather it would update associated cache metadata to complete the
write transaction with the cache device. IOW the writes to cached blocks still
go only to the cache device.
To write back dirty cache, as LVM cache did not support dirty cache flush per
block range, there'no way to do it for file. On the other hand the "cleaner"
policy is implemented and can be used to write back "all" dirty blocks in a
cache, which effectively drain all dirty cache gradually to attain and last in
the "clean" state, which can be useful for shrinking or decommissioning a
cache. The result and effect is not what we are looking for here.
In conclusion, as it seems no way to enforce file writes to the original
device, grub may suffer from power failure as it cannot assemble the cache
device and read the dirty data from it. However since the case is only
applicable to writeback mode which is sensitive to data lost in nature, I'd
still like to propose my (relatively simple) patch and treat reading dirty
cache as improvement.
Reference: http://git.savannah.gnu.org/cgit/grub.git/commit/grub-core/disk/lvm.c?id=0454b0445393aafc5600e92ef0c39494e333b135
Signed-off-by: Michael Chang <mchang@suse.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/disk/lvm.c | 191 ++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 190 insertions(+), 1 deletion(-)
diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c
index 85ee89c..e5d6c3f 100644
--- a/grub-core/disk/lvm.c
+++ b/grub-core/disk/lvm.c
@@ -34,7 +34,14 @@
GRUB_MOD_LICENSE ("GPLv3+");
-
+struct cache_lv
+{
+ struct grub_diskfilter_lv *lv;
+ char *cache_pool;
+ char *origin;
+ struct cache_lv *next;
+};
+
/* Go the string STR and return the number after STR. *P will point
at the number. In case STR is not found, *P will be NULL and the
return value will be 0. */
@@ -96,6 +103,34 @@ grub_lvm_check_flag (const char *p, const char *str, const char *flag)
}
}
+static void
+grub_lvm_free_cache_lvs (struct cache_lv *cache_lvs)
+{
+ struct cache_lv *cache;
+
+ while ((cache = cache_lvs))
+ {
+ cache_lvs = cache_lvs->next;
+
+ if (cache->lv)
+ {
+ unsigned int i;
+
+ for (i = 0; i < cache->lv->segment_count; ++i)
+ if (cache->lv->segments)
+ grub_free (cache->lv->segments[i].nodes);
+ grub_free (cache->lv->segments);
+ grub_free (cache->lv->fullname);
+ grub_free (cache->lv->idname);
+ grub_free (cache->lv->name);
+ }
+ grub_free (cache->lv);
+ grub_free (cache->origin);
+ grub_free (cache->cache_pool);
+ grub_free (cache);
+ }
+}
+
static struct grub_diskfilter_vg *
grub_lvm_detect (grub_disk_t disk,
struct grub_diskfilter_pv_id *id,
@@ -281,6 +316,8 @@ grub_lvm_detect (grub_disk_t disk,
if (! vg)
{
+ struct cache_lv *cache_lvs = NULL;
+
/* First time we see this volume group. We've to create the
whole volume group structure. */
vg = grub_malloc (sizeof (*vg));
@@ -742,6 +779,106 @@ grub_lvm_detect (grub_disk_t disk,
seg->nodes[seg->node_count - 1].name = tmp;
}
}
+ else if (grub_memcmp (p, "cache\"",
+ sizeof ("cache\"") - 1) == 0)
+ {
+ struct cache_lv *cache = NULL;
+
+ char *p2, *p3;
+ grub_size_t sz;
+
+ cache = grub_zalloc (sizeof (*cache));
+ if (!cache)
+ goto cache_lv_fail;
+ cache->lv = grub_zalloc (sizeof (*cache->lv));
+ if (!cache->lv)
+ goto cache_lv_fail;
+ grub_memcpy (cache->lv, lv, sizeof (*cache->lv));
+
+ if (lv->fullname)
+ {
+ cache->lv->fullname = grub_strdup (lv->fullname);
+ if (!cache->lv->fullname)
+ goto cache_lv_fail;
+ }
+ if (lv->idname)
+ {
+ cache->lv->idname = grub_strdup (lv->idname);
+ if (!cache->lv->idname)
+ goto cache_lv_fail;
+ }
+ if (lv->name)
+ {
+ cache->lv->name = grub_strdup (lv->name);
+ if (!cache->lv->name)
+ goto cache_lv_fail;
+ }
+
+ skip_lv = 1;
+
+ p2 = grub_strstr (p, "cache_pool = \"");
+ if (!p2)
+ goto cache_lv_fail;
+
+ p2 = grub_strchr (p2, '"');
+ if (!p2)
+ goto cache_lv_fail;
+
+ p3 = ++p2;
+ p3 = grub_strchr (p3, '"');
+ if (!p3)
+ goto cache_lv_fail;
+
+ sz = p3 - p2;
+
+ cache->cache_pool = grub_malloc (sz + 1);
+ if (!cache->cache_pool)
+ goto cache_lv_fail;
+ grub_memcpy (cache->cache_pool, p2, sz);
+ cache->cache_pool[sz] = '\0';
+
+ p2 = grub_strstr (p, "origin = \"");
+ if (!p2)
+ goto cache_lv_fail;
+
+ p2 = grub_strchr (p2, '"');
+ if (!p2)
+ goto cache_lv_fail;
+
+ p3 = ++p2;
+ p3 = grub_strchr (p3, '"');
+ if (!p3)
+ goto cache_lv_fail;
+
+ sz = p3 - p2;
+
+ cache->origin = grub_malloc (sz + 1);
+ if (!cache->origin)
+ goto cache_lv_fail;
+ grub_memcpy (cache->origin, p2, sz);
+ cache->origin[sz] = '\0';
+
+ cache->next = cache_lvs;
+ cache_lvs = cache;
+ break;
+
+ cache_lv_fail:
+ if (cache)
+ {
+ grub_free (cache->origin);
+ grub_free (cache->cache_pool);
+ if (cache->lv)
+ {
+ grub_free (cache->lv->fullname);
+ grub_free (cache->lv->idname);
+ grub_free (cache->lv->name);
+ }
+ grub_free (cache->lv);
+ grub_free (cache);
+ }
+ grub_lvm_free_cache_lvs (cache_lvs);
+ goto fail4;
+ }
else
{
#ifdef GRUB_UTIL
@@ -818,6 +955,58 @@ grub_lvm_detect (grub_disk_t disk,
}
}
+
+ {
+ struct cache_lv *cache;
+
+ for (cache = cache_lvs; cache; cache = cache->next)
+ {
+ struct grub_diskfilter_lv *lv;
+
+ for (lv = vg->lvs; lv; lv = lv->next)
+ if (grub_strcmp (lv->name, cache->origin) == 0)
+ break;
+ if (lv)
+ {
+ cache->lv->segments = grub_malloc (lv->segment_count * sizeof (*lv->segments));
+ if (!cache->lv->segments)
+ {
+ grub_lvm_free_cache_lvs (cache_lvs);
+ goto fail4;
+ }
+ grub_memcpy (cache->lv->segments, lv->segments, lv->segment_count * sizeof (*lv->segments));
+
+ for (i = 0; i < lv->segment_count; ++i)
+ {
+ struct grub_diskfilter_node *nodes = lv->segments[i].nodes;
+ grub_size_t node_count = lv->segments[i].node_count;
+
+ cache->lv->segments[i].nodes = grub_malloc (node_count * sizeof (*nodes));
+ if (!cache->lv->segments[i].nodes)
+ {
+ for (j = 0; j < i; ++j)
+ grub_free (cache->lv->segments[j].nodes);
+ grub_free (cache->lv->segments);
+ cache->lv->segments = NULL;
+ grub_lvm_free_cache_lvs (cache_lvs);
+ goto fail4;
+ }
+ grub_memcpy (cache->lv->segments[i].nodes, nodes, node_count * sizeof (*nodes));
+ }
+
+ if (cache->lv->segments)
+ {
+ cache->lv->segment_count = lv->segment_count;
+ cache->lv->vg = vg;
+ cache->lv->next = vg->lvs;
+ vg->lvs = cache->lv;
+ cache->lv = NULL;
+ }
+ }
+ }
+ }
+
+ grub_lvm_free_cache_lvs (cache_lvs);
if (grub_diskfilter_vg_register (vg))
goto fail4;
}
--
2.19.1

View File

@ -0,0 +1,130 @@
From 6a079d978c3c4c77da338b81880799146e47e6bf Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Thu, 21 Jan 2021 18:35:22 +1100
Subject: [PATCH] disk/lvm: Do not overread metadata
We could reach the end of valid metadata and not realize, leading to
some buffer overreads. Check if we have reached the end and bail.
Reference: http://git.savannah.gnu.org/cgit/grub.git/commit/?id=1155d7dffd3337942cb7583706b429d567d4db86
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/disk/lvm.c | 35 +++++++++++++++++++++++++++++------
1 file changed, 29 insertions(+), 6 deletions(-)
diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c
index e5d6c3f..a44861f 100644
--- a/grub-core/disk/lvm.c
+++ b/grub-core/disk/lvm.c
@@ -351,17 +351,23 @@ grub_lvm_detect (grub_disk_t disk,
while (1)
{
grub_ssize_t s;
- while (grub_isspace (*p))
+ while (grub_isspace (*p) && p < mda_end)
p++;
+ if (p == mda_end)
+ goto fail4;
+
if (*p == '}')
break;
pv = grub_zalloc (sizeof (*pv));
q = p;
- while (*q != ' ')
+ while (*q != ' ' && q < mda_end)
q++;
+ if (q == mda_end)
+ goto pvs_fail_noname;
+
s = q - p;
pv->name = grub_malloc (s + 1);
grub_memcpy (pv->name, p, s);
@@ -404,6 +410,7 @@ grub_lvm_detect (grub_disk_t disk,
continue;
pvs_fail:
grub_free (pv->name);
+ pvs_fail_noname:
grub_free (pv);
goto fail4;
}
@@ -425,18 +432,24 @@ grub_lvm_detect (grub_disk_t disk,
struct grub_diskfilter_segment *seg;
int is_pvmove;
- while (grub_isspace (*p))
+ while (grub_isspace (*p) && p < mda_end)
p++;
+ if (p == mda_end)
+ goto fail4;
+
if (*p == '}')
break;
lv = grub_zalloc (sizeof (*lv));
q = p;
- while (*q != ' ')
+ while (*q != ' ' && q < mda_end)
q++;
+ if (q == mda_end)
+ goto lvs_fail;
+
s = q - p;
lv->name = grub_strndup (p, s);
if (!lv->name)
@@ -608,9 +621,12 @@ grub_lvm_detect (grub_disk_t disk,
if (p == NULL)
goto lvs_segment_fail2;
q = ++p;
- while (*q != '"')
+ while (q < mda_end && *q != '"')
q++;
+ if (q == mda_end)
+ goto lvs_segment_fail2;
+
s = q - p;
stripe->name = grub_malloc (s + 1);
@@ -667,9 +683,12 @@ grub_lvm_detect (grub_disk_t disk,
if (p == NULL)
goto lvs_segment_fail2;
q = ++p;
- while (*q != '"')
+ while (q < mda_end && *q != '"')
q++;
+ if (q == mda_end)
+ goto lvs_segment_fail2;
+
s = q - p;
lvname = grub_malloc (s + 1);
@@ -825,6 +844,8 @@ grub_lvm_detect (grub_disk_t disk,
goto cache_lv_fail;
p3 = ++p2;
+ if (p3 == mda_end)
+ goto cache_lv_fail;
p3 = grub_strchr (p3, '"');
if (!p3)
goto cache_lv_fail;
@@ -846,6 +867,8 @@ grub_lvm_detect (grub_disk_t disk,
goto cache_lv_fail;
p3 = ++p2;
+ if (p3 == mda_end)
+ goto cache_lv_fail;
p3 = grub_strchr (p3, '"');
if (!p3)
goto cache_lv_fail;
--
2.19.1

View File

@ -0,0 +1,42 @@
From 6074485c541ef5b96acd051854e5ddad77acc858 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Fri, 22 Jan 2021 14:43:58 +1100
Subject: [PATCH] disk/lvm: Sanitize rlocn->offset to prevent wild read
rlocn->offset is read directly from disk and added to the metadatabuf
pointer to create a pointer to a block of metadata. It's a 64-bit
quantity so as long as you don't overflow you can set subsequent
pointers to point anywhere in memory.
Require that rlocn->offset fits within the metadata buffer size.
Reference: http://git.savannah.gnu.org/cgit/grub.git/commit/?id=701293684742d00133b39bf957d3642c81dc83f4
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/disk/lvm.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c
index a44861f..cf8f597 100644
--- a/grub-core/disk/lvm.c
+++ b/grub-core/disk/lvm.c
@@ -247,6 +247,14 @@ grub_lvm_detect (grub_disk_t disk,
}
rlocn = mdah->raw_locns;
+ if (grub_le_to_cpu64 (rlocn->offset) >= grub_le_to_cpu64 (mda_size))
+ {
+#ifdef GRUB_UTIL
+ grub_util_info ("metadata offset is beyond end of metadata area");
+#endif
+ goto fail2;
+ }
+
if (grub_le_to_cpu64 (rlocn->offset) + grub_le_to_cpu64 (rlocn->size) >
grub_le_to_cpu64 (mdah->size))
{
--
2.19.1

View File

@ -0,0 +1,40 @@
From 5ee2584caa3acd9289d2eedee38a9a73101aa1fe Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Fri, 22 Jan 2021 14:42:21 +1100
Subject: [PATCH] disk/lvm: Do not allow a LV to be it's own segment's node's
LV
This prevents infinite recursion in the diskfilter verification code.
Reference: http://git.savannah.gnu.org/cgit/grub.git/commit/?id=e18a00073890021362b4a48097672f1d4b340d3c
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/disk/lvm.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/grub-core/disk/lvm.c b/grub-core/disk/lvm.c
index cf8f597..7fb1b4e 100644
--- a/grub-core/disk/lvm.c
+++ b/grub-core/disk/lvm.c
@@ -980,9 +980,13 @@ grub_lvm_detect (grub_disk_t disk,
}
if (lv1->segments[i].nodes[j].pv == NULL)
for (lv2 = vg->lvs; lv2; lv2 = lv2->next)
- if (grub_strcmp (lv2->name,
- lv1->segments[i].nodes[j].name) == 0)
- lv1->segments[i].nodes[j].lv = lv2;
+ {
+ if (lv1 == lv2)
+ continue;
+ if (grub_strcmp (lv2->name,
+ lv1->segments[i].nodes[j].name) == 0)
+ lv1->segments[i].nodes[j].lv = lv2;
+ }
}
}
--
2.19.1

View File

@ -0,0 +1,34 @@
From 356c74f00ed24b08810dc236f37caaca228e5853 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Mon, 18 Jan 2021 17:17:16 +1100
Subject: [PATCH] fs/btrfs: Validate the number of stripes/parities in RAID5/6
This prevents a divide by zero if nstripes == nparities, and
also prevents propagation of invalid values if nstripes ends up
less than nparities.
Reference: http://git.savannah.gnu.org/cgit/grub.git/commit/?id=b88a82e78cdd0ab8e0339c1c3f9564c4d8c0c969
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/fs/btrfs.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c
index 0d8c666..a6384a8 100644
--- a/grub-core/fs/btrfs.c
+++ b/grub-core/fs/btrfs.c
@@ -1105,6 +1105,9 @@ grub_btrfs_read_logical (struct grub_btrfs_data *data, grub_disk_addr_t addr,
* stripen is computed without the parities
* (0 for A0, A1, A2, 1 for B0, B1, B2, etc.).
*/
+ if (nparities >= nstripes)
+ return grub_error (GRUB_ERR_BAD_FS,
+ "invalid RAID5/6: nparities >= nstripes");
high = grub_divmod64 (stripe_nr, nstripes - nparities, &stripen);
/*
--
2.19.1

View File

@ -0,0 +1,44 @@
From 498830861020ac6b713d002bb2e72f713860ea04 Mon Sep 17 00:00:00 2001
From: Daniel Axtens <dja@axtens.net>
Date: Mon, 18 Jan 2021 17:27:18 +1100
Subject: [PATCH] fs/btrfs: Squash some uninitialized reads
We need to check errors before calling into a function that uses the result.
Reference: http://git.savannah.gnu.org/cgit/grub.git/commit/?id=b911884dd707ba1e6f641eb17857df3155013a45
Signed-off-by: Daniel Axtens <dja@axtens.net>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/fs/btrfs.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/grub-core/fs/btrfs.c b/grub-core/fs/btrfs.c
index a6384a8..cf3647a 100644
--- a/grub-core/fs/btrfs.c
+++ b/grub-core/fs/btrfs.c
@@ -410,9 +410,9 @@ next (struct grub_btrfs_data *data,
err = grub_btrfs_read_logical (data, grub_le_to_cpu64 (node.addr),
&head, sizeof (head), 0);
- check_btrfs_header (data, &head, grub_le_to_cpu64 (node.addr));
if (err)
return -err;
+ check_btrfs_header (data, &head, grub_le_to_cpu64 (node.addr));
save_ref (desc, grub_le_to_cpu64 (node.addr), 0,
grub_le_to_cpu32 (head.nitems), !head.level);
@@ -472,9 +472,9 @@ lower_bound (struct grub_btrfs_data *data,
/* FIXME: preread few nodes into buffer. */
err = grub_btrfs_read_logical (data, addr, &head, sizeof (head),
recursion_depth + 1);
- check_btrfs_header (data, &head, addr);
if (err)
return err;
+ check_btrfs_header (data, &head, addr);
addr += sizeof (head);
if (head.level)
{
--
2.19.1

View File

@ -0,0 +1,305 @@
From f3821a98c9324f0f45bca9a1aed3921084a794ad Mon Sep 17 00:00:00 2001
From: Chris Coulson <chris.coulson@canonical.com>
Date: Tue, 1 Dec 2020 23:03:39 +0000
Subject: [PATCH] kern/efi: Add initial stack protector implementation
It works only on UEFI platforms but can be quite easily extended to
others architectures and platforms if needed.
Reference: http://git.savannah.gnu.org/cgit/grub.git/commit/?id=133d73079c5771bbf3d8311281b6772846357ec1
Signed-off-by: Chris Coulson <chris.coulson@canonical.com>
Signed-off-by: Daniel Kiper <daniel.kiper@oracle.com>
Reviewed-by: Marco A Benatto <mbenatto@redhat.com>
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
---
acinclude.m4 | 40 +++++++++++++++++++++++--
configure.ac | 44 +++++++++++++++++++++++----
grub-core/Makefile.am | 1 +
grub-core/kern/efi/init.c | 54 ++++++++++++++++++++++++++++++++++
include/grub/efi/api.h | 19 ++++++++++++
include/grub/stack_protector.h | 30 +++++++++++++++++++
6 files changed, 180 insertions(+), 8 deletions(-)
create mode 100644 include/grub/stack_protector.h
diff --git a/acinclude.m4 b/acinclude.m4
index 242e829..8eeed6f 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -323,10 +323,10 @@ else
fi
])
-
-dnl Check if the C compiler supports `-fstack-protector'.
+
+dnl Check if the C compiler supports the stack protector
AC_DEFUN([grub_CHECK_STACK_PROTECTOR],[
-[# Smashing stack protector.
+[# Stack smashing protector.
ssp_possible=yes]
AC_MSG_CHECKING([whether `$CC' accepts `-fstack-protector'])
# Is this a reliable test case?
@@ -343,6 +343,40 @@ else
ssp_possible=no]
AC_MSG_RESULT([no])
[fi]
+[# Strong stack smashing protector.
+ssp_strong_possible=yes]
+AC_MSG_CHECKING([whether `$CC' accepts `-fstack-protector-strong'])
+# Is this a reliable test case?
+AC_LANG_CONFTEST([AC_LANG_SOURCE([[
+void foo (void) { volatile char a[8]; a[3]; }
+]])])
+[# `$CC -c -o ...' might not be portable. But, oh, well... Is calling
+# `ac_compile' like this correct, after all?
+if eval "$ac_compile -S -fstack-protector-strong -o conftest.s" 2> /dev/null; then]
+ AC_MSG_RESULT([yes])
+ [# Should we clear up other files as well, having called `AC_LANG_CONFTEST'?
+ rm -f conftest.s
+else
+ ssp_strong_possible=no]
+ AC_MSG_RESULT([no])
+[fi]
+[# Global stack smashing protector.
+ssp_global_possible=yes]
+AC_MSG_CHECKING([whether `$CC' accepts `-mstack-protector-guard=global'])
+# Is this a reliable test case?
+AC_LANG_CONFTEST([AC_LANG_SOURCE([[
+void foo (void) { volatile char a[8]; a[3]; }
+]])])
+[# `$CC -c -o ...' might not be portable. But, oh, well... Is calling
+# `ac_compile' like this correct, after all?
+if eval "$ac_compile -S -fstack-protector -mstack-protector-guard=global -o conftest.s" 2> /dev/null; then]
+ AC_MSG_RESULT([yes])
+ [# Should we clear up other files as well, having called `AC_LANG_CONFTEST'?
+ rm -f conftest.s
+else
+ ssp_global_possible=no]
+ AC_MSG_RESULT([no])
+[fi]
])
dnl Check if the C compiler supports `-mstack-arg-probe' (Cygwin).
diff --git a/configure.ac b/configure.ac
index 5d33161..da735a6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1371,12 +1371,41 @@ fi]
CFLAGS="$TARGET_CFLAGS"
-# Smashing stack protector.
+# Stack smashing protector.
grub_CHECK_STACK_PROTECTOR
-# Need that, because some distributions ship compilers that include
-# `-fstack-protector' in the default specs.
-if test "x$ssp_possible" = xyes; then
- TARGET_CFLAGS="$TARGET_CFLAGS -fno-stack-protector"
+AC_ARG_ENABLE([stack-protector],
+ AS_HELP_STRING([--enable-stack-protector],
+ [enable the stack protector]),
+ [],
+ [enable_stack_protector=no])
+if test "x$enable_stack_protector" = xno; then
+ if test "x$ssp_possible" = xyes; then
+ # Need that, because some distributions ship compilers that include
+ # `-fstack-protector' in the default specs.
+ TARGET_CFLAGS="$TARGET_CFLAGS -fno-stack-protector"
+ fi
+elif test "x$platform" != xefi; then
+ AC_MSG_ERROR([--enable-stack-protector is only supported on EFI platforms])
+elif test "x$ssp_global_possible" != xyes; then
+ AC_MSG_ERROR([--enable-stack-protector is not supported (compiler doesn't support -mstack-protector-guard=global)])
+else
+ TARGET_CFLAGS="$TARGET_CFLAGS -mstack-protector-guard=global"
+ if test "x$enable_stack_protector" = xyes; then
+ if test "x$ssp_possible" != xyes; then
+ AC_MSG_ERROR([--enable-stack-protector is not supported (compiler doesn't support -fstack-protector)])
+ fi
+ TARGET_CFLAGS="$TARGET_CFLAGS -fstack-protector"
+ elif test "x$enable_stack_protector" = xstrong; then
+ if test "x$ssp_strong_possible" != xyes; then
+ AC_MSG_ERROR([--enable-stack-protector=strong is not supported (compiler doesn't support -fstack-protector-strong)])
+ fi
+ TARGET_CFLAGS="$TARGET_CFLAGS -fstack-protector-strong"
+ else
+ # Note, -fstack-protector-all requires that the protector is disabled for
+ # functions that appear in the call stack when the canary is initialized.
+ AC_MSG_ERROR([invalid value $enable_stack_protector for --enable-stack-protector])
+ fi
+ TARGET_CPPFLAGS="$TARGET_CPPFLAGS -DGRUB_STACK_PROTECTOR=1"
fi
CFLAGS="$TARGET_CFLAGS"
@@ -2279,5 +2308,10 @@ echo "Without liblzma (no support for XZ-compressed mips images) ($liblzma_excus
else
echo "With liblzma from $LIBLZMA (support for XZ-compressed mips images)"
fi
+if test "x$enable_stack_protector" != xno; then
+echo "With stack smashing protector: Yes"
+else
+echo "With stack smashing protector: No"
+fi
echo "*******************************************************"
]
diff --git a/grub-core/Makefile.am b/grub-core/Makefile.am
index d75feef..dd49939 100644
--- a/grub-core/Makefile.am
+++ b/grub-core/Makefile.am
@@ -92,6 +92,7 @@ endif
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/mm.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/parser.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/partition.h
+KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/stack_protector.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/term.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/time.h
KERNEL_HEADER_FILES += $(top_srcdir)/include/grub/verify.h
diff --git a/grub-core/kern/efi/init.c b/grub-core/kern/efi/init.c
index 634e3ac..8054fdd 100644
--- a/grub-core/kern/efi/init.c
+++ b/grub-core/kern/efi/init.c
@@ -28,6 +28,58 @@
#include <grub/mm.h>
#include <grub/kernel.h>
#include <grub/lib/envblk.h>
+#include <grub/stack_protector.h>
+
+#ifdef GRUB_STACK_PROTECTOR
+
+static grub_efi_guid_t rng_protocol_guid = GRUB_EFI_RNG_PROTOCOL_GUID;
+
+/*
+ * Don't put this on grub_efi_init()'s local stack to avoid it
+ * getting a stack check.
+ */
+static grub_efi_uint8_t stack_chk_guard_buf[32];
+
+grub_addr_t __stack_chk_guard;
+
+void __attribute__ ((noreturn))
+__stack_chk_fail (void)
+{
+ /*
+ * Assume it's not safe to call into EFI Boot Services. Sorry, that
+ * means no console message here.
+ */
+ do
+ {
+ /* Do not optimize out the loop. */
+ asm volatile ("");
+ }
+ while (1);
+}
+
+static void
+stack_protector_init (void)
+{
+ grub_efi_rng_protocol_t *rng;
+
+ /* Set up the stack canary. Make errors here non-fatal for now. */
+ rng = grub_efi_locate_protocol (&rng_protocol_guid, NULL);
+ if (rng != NULL)
+ {
+ grub_efi_status_t status;
+
+ status = efi_call_4 (rng->get_rng, rng, NULL, sizeof (stack_chk_guard_buf),
+ stack_chk_guard_buf);
+ if (status == GRUB_EFI_SUCCESS)
+ grub_memcpy (&__stack_chk_guard, stack_chk_guard_buf, sizeof (__stack_chk_guard));
+ }
+}
+#else
+static void
+stack_protector_init (void)
+{
+}
+#endif
grub_addr_t grub_modbase;
@@ -87,6 +139,8 @@ grub_efi_init (void)
messages. */
grub_console_init ();
+ stack_protector_init ();
+
/* Initialize the memory management system. */
grub_efi_mm_init ();
diff --git a/include/grub/efi/api.h b/include/grub/efi/api.h
index fc8a564..0e7e926 100644
--- a/include/grub/efi/api.h
+++ b/include/grub/efi/api.h
@@ -344,6 +344,11 @@
{ 0x89, 0x29, 0x48, 0xbc, 0xd9, 0x0a, 0xd3, 0x1a } \
}
+#define GRUB_EFI_RNG_PROTOCOL_GUID \
+ { 0x3152bca5, 0xeade, 0x433d, \
+ { 0x86, 0x2e, 0xc0, 0x1c, 0xdc, 0x29, 0x1f, 0x44 } \
+ }
+
struct grub_efi_sal_system_table
{
grub_uint32_t signature;
@@ -2062,6 +2067,20 @@ struct grub_efi_ip6_config_manual_address {
};
typedef struct grub_efi_ip6_config_manual_address grub_efi_ip6_config_manual_address_t;
+typedef grub_efi_guid_t grub_efi_rng_algorithm_t;
+
+struct grub_efi_rng_protocol
+{
+ grub_efi_status_t (*get_info) (struct grub_efi_rng_protocol *this,
+ grub_efi_uintn_t *rng_algorithm_list_size,
+ grub_efi_rng_algorithm_t *rng_algorithm_list);
+ grub_efi_status_t (*get_rng) (struct grub_efi_rng_protocol *this,
+ grub_efi_rng_algorithm_t *rng_algorithm,
+ grub_efi_uintn_t rng_value_length,
+ grub_efi_uint8_t *rng_value);
+};
+typedef struct grub_efi_rng_protocol grub_efi_rng_protocol_t;
+
#if (GRUB_TARGET_SIZEOF_VOID_P == 4) || defined (__ia64__) \
|| defined (__aarch64__) || defined (__MINGW64__) || defined (__CYGWIN__) \
|| defined(__riscv)
diff --git a/include/grub/stack_protector.h b/include/grub/stack_protector.h
new file mode 100644
index 0000000..c88dc00
--- /dev/null
+++ b/include/grub/stack_protector.h
@@ -0,0 +1,30 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2021 Free Software Foundation, Inc.
+ *
+ * GRUB is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * GRUB is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef GRUB_STACK_PROTECTOR_H
+#define GRUB_STACK_PROTECTOR_H 1
+
+#include <grub/symbol.h>
+#include <grub/types.h>
+
+#ifdef GRUB_STACK_PROTECTOR
+extern grub_addr_t EXPORT_VAR (__stack_chk_guard);
+extern void __attribute__ ((noreturn)) EXPORT_FUNC (__stack_chk_fail) (void);
+#endif
+
+#endif /* GRUB_STACK_PROTECTOR_H */
--
2.19.1

View File

@ -0,0 +1,62 @@
From 5ee52e31fb8bb37ef11cf3dbff933465944d9e32 Mon Sep 17 00:00:00 2001
From: Javier Martinez Canillas <javierm@redhat.com>
Date: Thu, 11 Feb 2021 17:06:49 +0100
Subject: [PATCH] util/mkimage: Remove unused code to add BSS section
The code is compiled out so there is no reason to keep it.
Additionally, don't set bss_size field since we do not add a BSS section.
Reference: http://git.savannah.gnu.org/cgit/grub.git/commit/?id=d52f78def1b9c4f435fdbf6b24fd899208580c76
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
util/mkimage.c | 17 -----------------
1 file changed, 17 deletions(-)
diff --git a/util/mkimage.c b/util/mkimage.c
index 37d6249..048089f 100644
--- a/util/mkimage.c
+++ b/util/mkimage.c
@@ -1304,7 +1304,6 @@ grub_install_generate_image (const char *dir, const char *prefix,
o->code_size = grub_host_to_target32 (layout.exec_size);
o->data_size = grub_cpu_to_le32 (reloc_addr - layout.exec_size
- header_size);
- o->bss_size = grub_cpu_to_le32 (layout.bss_size);
o->entry_addr = grub_cpu_to_le32 (layout.start_address);
o->code_base = grub_cpu_to_le32 (header_size);
@@ -1342,7 +1341,6 @@ grub_install_generate_image (const char *dir, const char *prefix,
o->code_size = grub_host_to_target32 (layout.exec_size);
o->data_size = grub_cpu_to_le32 (reloc_addr - layout.exec_size
- header_size);
- o->bss_size = grub_cpu_to_le32 (layout.bss_size);
o->entry_addr = grub_cpu_to_le32 (layout.start_address);
o->code_base = grub_cpu_to_le32 (header_size);
o->image_base = 0;
@@ -1388,21 +1386,6 @@ grub_install_generate_image (const char *dir, const char *prefix,
| GRUB_PE32_SCN_MEM_READ
| GRUB_PE32_SCN_MEM_WRITE);
-#if 0
- bss_section = data_section + 1;
- strcpy (bss_section->name, ".bss");
- bss_section->virtual_size = grub_cpu_to_le32 (layout.bss_size);
- bss_section->virtual_address = grub_cpu_to_le32 (header_size + layout.kernel_size);
- bss_section->raw_data_size = 0;
- bss_section->raw_data_offset = 0;
- bss_section->characteristics
- = grub_cpu_to_le32_compile_time (GRUB_PE32_SCN_MEM_READ
- | GRUB_PE32_SCN_MEM_WRITE
- | GRUB_PE32_SCN_ALIGN_64BYTES
- | GRUB_PE32_SCN_CNT_INITIALIZED_DATA
- | 0x80);
-#endif
-
mods_section = data_section + 1;
strcpy (mods_section->name, "mods");
mods_section->virtual_size = grub_cpu_to_le32 (reloc_addr - layout.kernel_size - header_size);
--
2.19.1

View File

@ -0,0 +1,114 @@
From fe56aca056a6bb39b3968e37a6e4df079419ca2c Mon Sep 17 00:00:00 2001
From: Peter Jones <pjones@redhat.com>
Date: Mon, 15 Feb 2021 13:59:21 +0100
Subject: [PATCH] util/mkimage: Use grub_host_to_target32() instead of
grub_cpu_to_le32()
The latter doesn't take into account the target image endianness. There is
a grub_cpu_to_le32_compile_time() but no compile time variant for function
grub_host_to_target32(). So, let's keep using the other one for this case.
Reference: http://git.savannah.gnu.org/cgit/grub.git/commit/?id=1710452aca05ccdd21e74390ec08c63fdf0ee10a
Signed-off-by: Peter Jones <pjones@redhat.com>
Signed-off-by: Javier Martinez Canillas <javierm@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
util/mkimage.c | 44 ++++++++++++++++++++++----------------------
1 file changed, 22 insertions(+), 22 deletions(-)
diff --git a/util/mkimage.c b/util/mkimage.c
index 048089f..47cd705 100644
--- a/util/mkimage.c
+++ b/util/mkimage.c
@@ -1302,10 +1302,10 @@ grub_install_generate_image (const char *dir, const char *prefix,
+ sizeof (struct grub_pe32_coff_header));
o->magic = grub_host_to_target16 (GRUB_PE32_PE32_MAGIC);
o->code_size = grub_host_to_target32 (layout.exec_size);
- o->data_size = grub_cpu_to_le32 (reloc_addr - layout.exec_size
+ o->data_size = grub_host_to_target32 (reloc_addr - layout.exec_size
- header_size);
- o->entry_addr = grub_cpu_to_le32 (layout.start_address);
- o->code_base = grub_cpu_to_le32 (header_size);
+ o->entry_addr = grub_host_to_target32 (layout.start_address);
+ o->code_base = grub_host_to_target32 (header_size);
o->data_base = grub_host_to_target32 (header_size + layout.exec_size);
@@ -1339,10 +1339,10 @@ grub_install_generate_image (const char *dir, const char *prefix,
+ sizeof (struct grub_pe32_coff_header));
o->magic = grub_host_to_target16 (GRUB_PE32_PE64_MAGIC);
o->code_size = grub_host_to_target32 (layout.exec_size);
- o->data_size = grub_cpu_to_le32 (reloc_addr - layout.exec_size
+ o->data_size = grub_host_to_target32 (reloc_addr - layout.exec_size
- header_size);
- o->entry_addr = grub_cpu_to_le32 (layout.start_address);
- o->code_base = grub_cpu_to_le32 (header_size);
+ o->entry_addr = grub_host_to_target32 (layout.start_address);
+ o->code_base = grub_host_to_target32 (header_size);
o->image_base = 0;
o->section_alignment = grub_host_to_target32 (image_target->section_align);
o->file_alignment = grub_host_to_target32 (GRUB_PE32_FILE_ALIGNMENT);
@@ -1366,10 +1366,10 @@ grub_install_generate_image (const char *dir, const char *prefix,
/* The sections. */
text_section = sections;
strcpy (text_section->name, ".text");
- text_section->virtual_size = grub_cpu_to_le32 (layout.exec_size);
- text_section->virtual_address = grub_cpu_to_le32 (header_size);
- text_section->raw_data_size = grub_cpu_to_le32 (layout.exec_size);
- text_section->raw_data_offset = grub_cpu_to_le32 (header_size);
+ text_section->virtual_size = grub_host_to_target32 (layout.exec_size);
+ text_section->virtual_address = grub_host_to_target32 (header_size);
+ text_section->raw_data_size = grub_host_to_target32 (layout.exec_size);
+ text_section->raw_data_offset = grub_host_to_target32 (header_size);
text_section->characteristics = grub_cpu_to_le32_compile_time (
GRUB_PE32_SCN_CNT_CODE
| GRUB_PE32_SCN_MEM_EXECUTE
@@ -1377,10 +1377,10 @@ grub_install_generate_image (const char *dir, const char *prefix,
data_section = text_section + 1;
strcpy (data_section->name, ".data");
- data_section->virtual_size = grub_cpu_to_le32 (layout.kernel_size - layout.exec_size);
- data_section->virtual_address = grub_cpu_to_le32 (header_size + layout.exec_size);
- data_section->raw_data_size = grub_cpu_to_le32 (layout.kernel_size - layout.exec_size);
- data_section->raw_data_offset = grub_cpu_to_le32 (header_size + layout.exec_size);
+ data_section->virtual_size = grub_host_to_target32 (layout.kernel_size - layout.exec_size);
+ data_section->virtual_address = grub_host_to_target32 (header_size + layout.exec_size);
+ data_section->raw_data_size = grub_host_to_target32 (layout.kernel_size - layout.exec_size);
+ data_section->raw_data_offset = grub_host_to_target32 (header_size + layout.exec_size);
data_section->characteristics
= grub_cpu_to_le32_compile_time (GRUB_PE32_SCN_CNT_INITIALIZED_DATA
| GRUB_PE32_SCN_MEM_READ
@@ -1388,10 +1388,10 @@ grub_install_generate_image (const char *dir, const char *prefix,
mods_section = data_section + 1;
strcpy (mods_section->name, "mods");
- mods_section->virtual_size = grub_cpu_to_le32 (reloc_addr - layout.kernel_size - header_size);
- mods_section->virtual_address = grub_cpu_to_le32 (header_size + layout.kernel_size + layout.bss_size);
- mods_section->raw_data_size = grub_cpu_to_le32 (reloc_addr - layout.kernel_size - header_size);
- mods_section->raw_data_offset = grub_cpu_to_le32 (header_size + layout.kernel_size);
+ mods_section->virtual_size = grub_host_to_target32 (reloc_addr - layout.kernel_size - header_size);
+ mods_section->virtual_address = grub_host_to_target32 (header_size + layout.kernel_size + layout.bss_size);
+ mods_section->raw_data_size = grub_host_to_target32 (reloc_addr - layout.kernel_size - header_size);
+ mods_section->raw_data_offset = grub_host_to_target32 (header_size + layout.kernel_size);
mods_section->characteristics
= grub_cpu_to_le32_compile_time (GRUB_PE32_SCN_CNT_INITIALIZED_DATA
| GRUB_PE32_SCN_MEM_READ
@@ -1399,10 +1399,10 @@ grub_install_generate_image (const char *dir, const char *prefix,
reloc_section = mods_section + 1;
strcpy (reloc_section->name, ".reloc");
- reloc_section->virtual_size = grub_cpu_to_le32 (layout.reloc_size);
- reloc_section->virtual_address = grub_cpu_to_le32 (reloc_addr + layout.bss_size);
- reloc_section->raw_data_size = grub_cpu_to_le32 (layout.reloc_size);
- reloc_section->raw_data_offset = grub_cpu_to_le32 (reloc_addr);
+ reloc_section->virtual_size = grub_host_to_target32 (layout.reloc_size);
+ reloc_section->virtual_address = grub_host_to_target32 (reloc_addr + layout.bss_size);
+ reloc_section->raw_data_size = grub_host_to_target32 (layout.reloc_size);
+ reloc_section->raw_data_offset = grub_host_to_target32 (reloc_addr);
reloc_section->characteristics
= grub_cpu_to_le32_compile_time (GRUB_PE32_SCN_CNT_INITIALIZED_DATA
| GRUB_PE32_SCN_MEM_DISCARDABLE
--
2.19.1

View File

@ -0,0 +1,34 @@
From 4a2ba9ed2b2d058b9692ae86ce06b0d485a86ad5 Mon Sep 17 00:00:00 2001
From: Marco A Benatto <mbenatto@redhat.com>
Date: Tue, 9 Feb 2021 12:33:06 -0300
Subject: [PATCH] kern/mm: Fix grub_debug_calloc() compilation error
Fix compilation error due to missing parameter to
grub_printf() when MM_DEBUG is defined.
Fixes: 64e26162e (calloc: Make sure we always have an overflow-checking calloc() available)
Reference: http://git.savannah.gnu.org/cgit/grub.git/commit/?id=a9d8de960834f376087856f9d60a214b47c76f61
Signed-off-by: Marco A Benatto <mbenatto@redhat.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/kern/mm.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/grub-core/kern/mm.c b/grub-core/kern/mm.c
index 80d0720..d8c8377 100644
--- a/grub-core/kern/mm.c
+++ b/grub-core/kern/mm.c
@@ -594,7 +594,7 @@ grub_debug_calloc (const char *file, int line, grub_size_t nmemb, grub_size_t si
if (grub_mm_debug)
grub_printf ("%s:%d: calloc (0x%" PRIxGRUB_SIZE ", 0x%" PRIxGRUB_SIZE ") = ",
- file, line, size);
+ file, line, nmemb, size);
ptr = grub_calloc (nmemb, size);
if (grub_mm_debug)
grub_printf ("%p\n", ptr);
--
2.19.1

View File

@ -271,3 +271,75 @@ Patch0270: backport-0009-CVE-2020-27779-and-CVE-2020-14372.patch
Patch0271: backport-0010-CVE-2020-27779-and-CVE-2020-14372.patch
Patch0272: backport-0011-CVE-2020-27779-and-CVE-2020-14372.patch
Patch0273: backport-0012-CVE-2020-27779-and-CVE-2020-14372.patch
Patch0274: backport-0001-mmap-Fix-memory-leak-when-iterating-over-mapped-memo.patch
Patch0275: backport-0002-net-net-Fix-possible-dereference-to-of-a-NULL-pointe.patch
Patch0276: backport-0003-net-tftp-Fix-dangling-memory-pointer.patch
Patch0277: backport-0004-kern-efi-Fix-memory-leak-on-failure.patch
Patch0278: backport-0005-kern-efi-mm-Fix-possible-NULL-pointer-dereference.patch
Patch0279: backport-0006-zstd-Initialize-seq_t-structure-fully.patch
Patch0280: backport-0007-kern-partition-Check-for-NULL-before-dereferencing-i.patch
Patch0281: backport-0008-disk-ldm-Make-sure-comp-data-is-freed-before-exiting.patch
Patch0282: backport-0009-disk-ldm-If-failed-then-free-vg-variable-too.patch
Patch0283: backport-0010-disk-ldm-Fix-memory-leak-on-uninserted-lv-references.patch
Patch0284: backport-0011-hfsplus-Check-that-the-volume-name-length-is-valid.patch
Patch0285: backport-0012-zfs-Fix-possible-negative-shift-operation.patch
Patch0286: backport-0013-zfs-Fix-resource-leaks-while-constructing-path.patch
Patch0287: backport-0014-zfs-Fix-possible-integer-overflows.patch
Patch0288: backport-0015-zfsinfo-Correct-a-check-for-error-allocating-memory.patch
Patch0289: backport-0016-affs-Fix-memory-leaks.patch
Patch0290: backport-0017-libgcrypt-mpi-Fix-possible-unintended-sign-extension.patch
Patch0291: backport-0018-libgcrypt-mpi-Fix-possible-NULL-dereference.patch
Patch0292: backport-0019-syslinux-Fix-memory-leak-while-parsing.patch
Patch0293: backport-0020-normal-completion-Fix-leaking-of-memory-when-process.patch
Patch0294: backport-0021-commands-hashsum-Fix-a-memory-leak.patch
Patch0295: backport-0022-video-efi_gop-Remove-unnecessary-return-value-of-gru.patch
Patch0296: backport-0023-video-fb-fbfill-Fix-potential-integer-overflow.patch
Patch0297: backport-0024-video-fb-video_fb-Fix-multiple-integer-overflows.patch
Patch0298: backport-0025-video-fb-video_fb-Fix-possible-integer-overflow.patch
Patch0299: backport-0026-video-readers-jpeg-Test-for-an-invalid-next-marker-r.patch
Patch0300: backport-0027-gfxmenu-gui_list-Remove-code-that-coverity-is-flaggi.patch
Patch0301: backport-0028-loader-bsd-Check-for-NULL-arg-up-front.patch
Patch0302: backport-0029-loader-xnu-Fix-memory-leak.patch
Patch0303: backport-0030-loader-xnu-Free-driverkey-data-when-an-error-is-dete.patch
Patch0304: backport-0031-loader-xnu-Check-if-pointer-is-NULL-before-using-it.patch
Patch0305: backport-0032-util-grub-install-Fix-NULL-pointer-dereferences.patch
Patch0306: backport-0033-util-grub-editenv-Fix-incorrect-casting-of-a-signed-.patch
Patch0307: backport-0034-util-glue-efi-Fix-incorrect-use-of-a-possibly-negati.patch
Patch0308: backport-0035-script-execute-Fix-NULL-dereference-in-grub_script_e.patch
Patch0309: backport-0036-commands-ls-Require-device_name-is-not-NULL-before-p.patch
Patch0310: backport-0037-script-execute-Avoid-crash-when-using-outside-a-func.patch
Patch0311: backport-0038-script-execute-Don-t-crash-on-a-for-loop-with-no-ite.patch
Patch0312: backport-0039-kern-misc-Always-set-end-in-grub_strtoull.patch
Patch0313: backport-0040-video-readers-jpeg-Catch-files-with-unsupported-quan.patch
Patch0314: backport-0041-video-readers-jpeg-Catch-OOB-reads-writes-in-grub_jp.patch
Patch0315: backport-0042-video-readers-jpeg-Don-t-decode-data-before-start-of.patch
Patch0316: backport-0043-term-gfxterm-Don-t-set-up-a-font-with-glyphs-that-ar.patch
Patch0317: backport-0044-fs-fshelp-Catch-impermissibly-large-block-sizes-in-r.patch
Patch0318: backport-0045-fs-hfsplus-Don-t-fetch-a-key-beyond-the-end-of-the-n.patch
Patch0319: backport-0046-fs-hfsplus-Don-t-use-uninitialized-data-on-corrupt-f.patch
Patch0320: backport-0047-fs-hfs-Disable-under-lockdown.patch
Patch0321: backport-0048-fs-sfs-Fix-over-read-of-root-object-name.patch
Patch0322: backport-0049-fs-jfs-Do-not-move-to-leaf-level-if-name-length-is-n.patch
Patch0323: backport-0050-fs-jfs-Limit-the-extents-that-getblk-can-consider.patch
Patch0324: backport-0051-fs-jfs-Catch-infinite-recursion.patch
Patch0325: backport-0052-fs-nilfs2-Reject-too-large-keys.patch
Patch0326: backport-0053-fs-nilfs2-Don-t-search-children-if-provided-number-i.patch
Patch0327: backport-0054-fs-nilfs2-Properly-bail-on-errors-in-grub_nilfs2_btr.patch
Patch0328: backport-0055-io-gzio-Bail-if-gzio-tl-td-is-NULL.patch
Patch0329: backport-0056-io-gzio-Add-init_dynamic_block-clean-up-if-unpacking.patch
Patch0330: backport-0057-io-gzio-Catch-missing-values-in-huft_build-and-bail.patch
Patch0331: backport-0058-io-gzio-Zero-gzio-tl-td-in-init_dynamic_block-if-huf.patch
Patch0332: backport-0059-disk-lvm-Don-t-go-beyond-the-end-of-the-data-we-read.patch
Patch0333: backport-0060-disk-lvm-Don-t-blast-past-the-end-of-the-circular-me.patch
Patch0334: backport-0061-disk-lvm-Bail-on-missing-PV-list.patch
Patch0335: backport-0062-disk-lvm-Do-not-crash-if-an-expected-string-is-not-f.patch
Patch0336: backport-0063-lvm-Add-LVM-cache-logical-volume-handling.patch
Patch0337: backport-0064-disk-lvm-Do-not-overread-metadata.patch
Patch0338: backport-0065-disk-lvm-Sanitize-rlocn-offset-to-prevent-wild-read.patch
Patch0339: backport-0066-disk-lvm-Do-not-allow-a-LV-to-be-it-s-own-segment-s-.patch
Patch0340: backport-0067-fs-btrfs-Validate-the-number-of-stripes-parities-in-.patch
Patch0341: backport-0068-fs-btrfs-Squash-some-uninitialized-reads.patch
Patch0342: backport-0069-kern-efi-Add-initial-stack-protector-implementation.patch
Patch0343: backport-0070-util-mkimage-Remove-unused-code-to-add-BSS-section.patch
Patch0344: backport-0071-util-mkimage-Use-grub_host_to_target32-instead-of-gr.patch
Patch0345: backport-0072-kern-mm-Fix-grub_debug_calloc-compilation-error.patch

View File

@ -8,7 +8,7 @@
Name: grub2
Epoch: 1
Version: 2.04
Release: 14
Release: 15
Summary: Bootloader with support for Linux, Multiboot and more
License: GPLv3+
URL: http://www.gnu.org/software/grub/
@ -449,6 +449,13 @@ rm -r /boot/grub2.tmp/ || :
%{_datadir}/man/man*
%changelog
* Mon Mar 29 2021 zhangqiumiao <zhangqiumiao1@huawei.com> - 2.04-15
- Type:bugfix
- ID:NA
- SUG:NA
- DESC:backport the patches that upstream community released on
March 2, 2021
* Mon Mar 29 2021 renmingshuai <renmingshuai@huawei.com> - 2.04-14
- Type:bugfix
- ID:NA