Compare commits

...

No commits in common. "c8" and "a8-beta" have entirely different histories.
c8 ... a8-beta

27 changed files with 1451 additions and 19 deletions

View File

@ -0,0 +1,30 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Matt Hsiao <matt.hsiao@hpe.com>
Date: Mon, 24 Apr 2023 13:39:05 +0800
Subject: [PATCH] efi/http: change uint32_t to uintn_t for
grub_efi_http_message_t
Modify UINT32 to UINTN in EFI_HTTP_MESSAGE to be UEFI 2.9 compliant.
Signed-off-by: Matt Hsiao <matt.hsiao@hpe.com>
Signed-off-by: Nicolas Frayer <nfrayer@redhat.com>
---
include/grub/efi/http.h | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/include/grub/efi/http.h b/include/grub/efi/http.h
index c5e9a89f5050..ad164ba1913d 100644
--- a/include/grub/efi/http.h
+++ b/include/grub/efi/http.h
@@ -171,9 +171,9 @@ typedef struct {
grub_efi_http_request_data_t *request;
grub_efi_http_response_data_t *response;
} data;
- grub_efi_uint32_t header_count;
+ grub_efi_uintn_t header_count;
grub_efi_http_header_t *headers;
- grub_efi_uint32_t body_length;
+ grub_efi_uintn_t body_length;
void *body;
} grub_efi_http_message_t;

View File

@ -0,0 +1,46 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Avnish Chouhan <avnish@linux.vnet.ibm.com>
Date: Thu, 23 Mar 2023 08:16:25 -0400
Subject: [PATCH] ieee1275 : Converting plain numbers to constants in Vec5
This patch converts the plain numbers used in Vec5 properties to
constants.
1. LPAR : Client program supports logical partitioning and
associated hcall()s.
2. SPLPAR : Client program supports the Shared
Processor LPAR Option.
3. CMO : Enables the Cooperative Memory Over-commitment Option.
4. MAX_CPU : Defines maximum number of CPUs supported.
Signed-off-by: Avnish Chouhan <avnish@linux.vnet.ibm.com>
---
grub-core/kern/ieee1275/init.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c
index 3ea9b73b2a59..2516e02091cb 100644
--- a/grub-core/kern/ieee1275/init.c
+++ b/grub-core/kern/ieee1275/init.c
@@ -56,6 +56,12 @@ extern char _end[];
grub_addr_t grub_ieee1275_original_stack;
#endif
+#define LPAR 0x80
+#define SPLPAR 0x40
+#define BYTE2 (LPAR | SPLPAR)
+#define CMO 0x80
+#define MAX_CPU 256
+
void
grub_exit (int rc __attribute__((unused)))
{
@@ -372,7 +378,7 @@ grub_ieee1275_ibm_cas (void)
.vec4 = 0x0001, // set required minimum capacity % to the lowest value
.vec5_size = 1 + sizeof(struct option_vector5) - 2,
.vec5 = {
- 0, 192, 0, 128, 0, 0, 0, 0, 256
+ 0, BYTE2, 0, CMO, 0, 0, 0, 0, MAX_CPU
}
};

View File

@ -0,0 +1,125 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Avnish Chouhan <avnish@linux.vnet.ibm.com>
Date: Thu, 23 Mar 2023 08:33:12 -0400
Subject: [PATCH] ieee1275 : extended support in options vector5
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This patch enables the multiple options in Options Vector5 which are
required and solves the boot issue seen on some machines which are looking for these specific options.
1. LPAR : Client program supports logical partitioning and
associated hcall()s.
2. SPLPAR : Client program supports the Shared
Processor LPAR Option.
3. DYN_RCON_MEM : Client program supports the
“ibm,dynamic-reconfiguration-memory” property and it may be
presented in the device tree.
4. LARGE_PAGES : Client supports pages larger than 4 KB.
5. DONATE_DCPU_CLS : Client supports donating dedicated processor cycles.
6. PCI_EXP : Client supports PCI Express implementations
utilizing Message Signaled Interrupts (MSIs).
7. CMOC : Enables the Cooperative Memory Over-commitment Option.
8. EXT_CMO : Enables the Extended Cooperative Memory Over-commit
Option.
9. ASSOC_REF : Enables “ibm,associativity” and
“ibm,associativity-reference-points” properties.
10. AFFINITY : Enables Platform Resource Reassignment Notification.
11. NUMA : Supports NUMA Distance Lookup Table Option.
12. HOTPLUG_INTRPT : Supports Hotplug Interrupts.
13. HPT_RESIZE : Enable Hash Page Table Resize Option.
14. MAX_CPU : Defines maximum number of CPUs supported.
15. PFO_HWRNG : Supports Random Number Generator.
16. PFO_HW_COMP : Supports Compression Engine.
17. PFO_ENCRYPT : Supports Encryption Engine.
18. SUB_PROCESSORS : Supports Sub-Processors.
19. DY_MEM_V2 : Client program supports the “ibm,dynamic-memory-v2” property in the
“ibm,dynamic-reconfiguration-memory” node and it may be presented in the device tree.
20. DRC_INFO : Client program supports the “ibm,drc-info” property definition and it may be
presented in the device tree.
Signed-off-by: Avnish Chouhan <avnish@linux.vnet.ibm.com>
---
grub-core/kern/ieee1275/init.c | 47 ++++++++++++++++++++++++++++++++++++------
1 file changed, 41 insertions(+), 6 deletions(-)
diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c
index 2516e02091cb..1fae84440403 100644
--- a/grub-core/kern/ieee1275/init.c
+++ b/grub-core/kern/ieee1275/init.c
@@ -56,11 +56,41 @@ extern char _end[];
grub_addr_t grub_ieee1275_original_stack;
#endif
-#define LPAR 0x80
-#define SPLPAR 0x40
-#define BYTE2 (LPAR | SPLPAR)
-#define CMO 0x80
-#define MAX_CPU 256
+/* Options vector5 properties */
+
+#define LPAR 0x80
+#define SPLPAR 0x40
+#define DYN_RCON_MEM 0x20
+#define LARGE_PAGES 0x10
+#define DONATE_DCPU_CLS 0x02
+#define PCI_EXP 0x01
+#define BYTE2 (LPAR | SPLPAR | DYN_RCON_MEM | LARGE_PAGES | DONATE_DCPU_CLS | PCI_EXP)
+
+#define CMOC 0x80
+#define EXT_CMO 0x40
+#define CMO (CMOC | EXT_CMO)
+
+#define ASSOC_REF 0x80
+#define AFFINITY 0x40
+#define NUMA 0x20
+#define ASSOCIATIVITY (ASSOC_REF | AFFINITY | NUMA)
+
+#define HOTPLUG_INTRPT 0x04
+#define HPT_RESIZE 0x01
+#define BIN_OPTS (HOTPLUG_INTRPT | HPT_RESIZE)
+
+#define MAX_CPU 256
+
+#define PFO_HWRNG 0x80000000
+#define PFO_HW_COMP 0x40000000
+#define PFO_ENCRYPT 0x20000000
+#define PLATFORM_FACILITIES (PFO_HWRNG | PFO_HW_COMP | PFO_ENCRYPT)
+
+#define SUB_PROCESSORS 1
+
+#define DY_MEM_V2 0x80
+#define DRC_INFO 0x40
+#define BYTE22 (DY_MEM_V2 | DRC_INFO)
void
grub_exit (int rc __attribute__((unused)))
@@ -323,6 +353,11 @@ struct option_vector5 {
grub_uint8_t micro_checkpoint;
grub_uint8_t reserved0;
grub_uint32_t max_cpus;
+ grub_uint16_t base_PAPR;
+ grub_uint16_t mem_reference;
+ grub_uint32_t platform_facilities;
+ grub_uint8_t sub_processors;
+ grub_uint8_t byte22;
} __attribute__((packed));
struct pvr_entry {
@@ -378,7 +413,7 @@ grub_ieee1275_ibm_cas (void)
.vec4 = 0x0001, // set required minimum capacity % to the lowest value
.vec5_size = 1 + sizeof(struct option_vector5) - 2,
.vec5 = {
- 0, BYTE2, 0, CMO, 0, 0, 0, 0, MAX_CPU
+ 0, BYTE2, 0, CMO, ASSOCIATIVITY, BIN_OPTS, 0, 0, MAX_CPU, 0, 0, PLATFORM_FACILITIES, SUB_PROCESSORS, BYTE22
}
};

View File

@ -0,0 +1,36 @@
From 8c74431327e0c7d7fe47462b0e69fcbe3bbac56e Mon Sep 17 00:00:00 2001
From: Marta Lewandowska <mlewando@redhat.com>
Date: Fri, 24 Mar 2023 09:14:29 -0400
Subject: [PATCH] Regenerate kernelopts if missing on ppc
Signed-off-by: Marta Lewandowska <mlewando@redhat.com>
---
util/grub.d/10_linux_bls.in | 12 ++++++++++++
1 file changed, 12 insertions(+)
diff --git a/util/grub.d/10_linux_bls.in b/util/grub.d/10_linux_bls.in
index 855dbdd..f2281bc 100644
--- a/util/grub.d/10_linux_bls.in
+++ b/util/grub.d/10_linux_bls.in
@@ -117,6 +117,18 @@ cat <<EOF
# This section was generated by a script. Do not modify the generated file - all changes
# will be lost the next time file is regenerated. Instead edit the BootLoaderSpec files.
+# The kernelopts variable should be defined in the grubenv file. But to ensure that menu
+# entries populated from BootLoaderSpec files that use this variable work correctly even
+# without a grubenv file, define a fallback kernelopts variable if this has not been set.
+#
+# The kernelopts variable in the grubenv file can be modified using the grubby tool or by
+# executing the grub2-mkconfig tool. For the latter, the values of the GRUB_CMDLINE_LINUX
+# and GRUB_CMDLINE_LINUX_DEFAULT options from /etc/default/grub file are used to set both
+# the kernelopts variable in the grubenv file and the fallback kernelopts variable.
+if [ -z "\${kernelopts}" ]; then
+ set kernelopts="root=${linux_root_device_thisversion} ro ${args}"
+fi
+
EOF
}
--
2.39.1

View File

@ -0,0 +1,210 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Stefan Berger <stefanb@linux.ibm.com>
Date: Tue, 8 Aug 2023 12:21:55 -0400
Subject: [PATCH] kern/ieee1275/init: ppc64: Restrict high memory in presence
of fadump
This is a backport of the patch with the same name to grub 2.02.
When a kernel dump is present then restrict the high memory regions to
avoid allocating memory where the kernel dump resides. Use the
ibm,kernel-dump node under /rtas to determine whether a kernel dump exists
and up to which limit grub can use available memory. Set the
upper_mem_limit to the size of the kernel dump section of type
'REAL_MODE_REGION' and therefore only allow grub's memory usage for high
addresses from 768MB to 'upper_mem_limit'. This means that grub can
use high memory in the range of 768MB to upper_mem_limit and
the kernel-dump memory regions above 'upper_mem_limit' remain untouched.
This change has no effect on memory allocations below 640MB.
Also, fall back to allocating below 640MB in case the chunk of
memory there would be larger than the chunk of memory above 768MB.
This can for example occur if a free memory area is found starting at 300MB
extending up to 1GB but a kernel dump is located at 768MB and therefore
does not allow the allocation of the high memory area but requiring to use
the chunk starting at 300MB to avoid an unnecessary out-of-memory
condition.
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
Cc: Hari Bathini <hbathini@linux.ibm.com>
Cc: Pavithra Prakash <pavrampu@in.ibm.com>
Cc: Michael Ellerman <mpe@ellerman.id.au>
Cc: Carolyn Scherrer <cpscherr@us.ibm.com>
Cc: Mahesh Salgaonkar <mahesh@linux.ibm.com>
Cc: Sourabh Jain <sourabhjain@linux.ibm.com>
---
grub-core/kern/ieee1275/init.c | 139 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 139 insertions(+)
diff --git a/grub-core/kern/ieee1275/init.c b/grub-core/kern/ieee1275/init.c
index 1fae84440403..31843ab70a62 100644
--- a/grub-core/kern/ieee1275/init.c
+++ b/grub-core/kern/ieee1275/init.c
@@ -17,6 +17,8 @@
* along with GRUB. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <stddef.h> /* offsetof() */
+
#include <grub/kernel.h>
#include <grub/dl.h>
#include <grub/disk.h>
@@ -180,6 +182,97 @@ grub_claim_heap (void)
+ GRUB_KERNEL_MACHINE_STACK_SIZE), 0x200000);
}
#else
+
+/* ibm,kernel-dump data structures */
+struct kd_section
+{
+ grub_uint32_t flags;
+ grub_uint16_t src_datatype;
+#define KD_SRC_DATATYPE_REAL_MODE_REGION 0x0011
+ grub_uint16_t error_flags;
+ grub_uint64_t src_address;
+ grub_uint64_t num_bytes;
+ grub_uint64_t act_bytes;
+ grub_uint64_t dst_address;
+} GRUB_PACKED;
+
+#define MAX_KD_SECTIONS 10
+
+struct kernel_dump
+{
+ grub_uint32_t format;
+ grub_uint16_t num_sections;
+ grub_uint16_t status_flags;
+ grub_uint32_t offset_1st_section;
+ grub_uint32_t num_blocks;
+ grub_uint64_t start_block;
+ grub_uint64_t num_blocks_avail;
+ grub_uint32_t offet_path_string;
+ grub_uint32_t max_time_allowed;
+ struct kd_section kds[MAX_KD_SECTIONS]; /* offset_1st_section should point to kds[0] */
+} GRUB_PACKED;
+
+/*
+ * Determine if a kernel dump exists and if it does, then determine the highest
+ * address that grub can use for memory allocations.
+ * The caller must have initialized *highest to ~0. *highest will not
+ * be modified if no kernel dump is found.
+ */
+static int
+check_kernel_dump (grub_uint64_t *highest)
+{
+ struct kernel_dump kernel_dump;
+ grub_ssize_t kernel_dump_size;
+ grub_ieee1275_phandle_t rtas;
+ struct kd_section *kds;
+ grub_size_t i;
+
+ /* If there's a kernel-dump it must have at least one section */
+ if (grub_ieee1275_finddevice ("/rtas", &rtas) ||
+ grub_ieee1275_get_property (rtas, "ibm,kernel-dump", &kernel_dump,
+ sizeof (kernel_dump), &kernel_dump_size) ||
+ kernel_dump_size <= (grub_ssize_t) offsetof (struct kernel_dump, kds[1]))
+ return 0;
+
+ kernel_dump_size = grub_min (kernel_dump_size, (grub_ssize_t) sizeof (kernel_dump));
+
+ if (grub_be_to_cpu32 (kernel_dump.format) != 1)
+ {
+ grub_printf (_("Error: ibm,kernel-dump has an unexpected format version '%u'\n"),
+ grub_be_to_cpu32 (kernel_dump.format));
+ return 0;
+ }
+
+ if (grub_be_to_cpu16 (kernel_dump.num_sections) > MAX_KD_SECTIONS)
+ {
+ grub_printf (_("Error: Too many kernel dump sections: %d\n"),
+ grub_be_to_cpu32 (kernel_dump.num_sections));
+ return 0;
+ }
+
+ for (i = 0; i < grub_be_to_cpu16 (kernel_dump.num_sections); i++)
+ {
+ kds = (struct kd_section *) ((grub_addr_t) &kernel_dump +
+ grub_be_to_cpu32 (kernel_dump.offset_1st_section) +
+ i * sizeof (struct kd_section));
+ /* sanity check the address is within the 'kernel_dump' struct */
+ if ((grub_addr_t) kds > (grub_addr_t) &kernel_dump + kernel_dump_size + sizeof (*kds))
+ {
+ grub_printf (_("Error: 'kds' address beyond last available section\n"));
+ return 0;
+ }
+
+ if ((grub_be_to_cpu16 (kds->src_datatype) == KD_SRC_DATATYPE_REAL_MODE_REGION) &&
+ (grub_be_to_cpu64 (kds->src_address) == 0))
+ {
+ *highest = grub_min (*highest, grub_be_to_cpu64 (kds->num_bytes));
+ break;
+ }
+ }
+
+ return 1;
+}
+
/* Helper for grub_claim_heap on powerpc. */
static int
heap_size (grub_uint64_t addr, grub_uint64_t len, grub_memory_type_t type,
@@ -207,7 +300,9 @@ static int
heap_init (grub_uint64_t addr, grub_uint64_t len, grub_memory_type_t type,
void *data)
{
+ grub_uint64_t upper_mem_limit = ~0;
grub_uint32_t total = *(grub_uint32_t *)data;
+ int has_kernel_dump;
if (type != GRUB_MEMORY_AVAILABLE)
return 0;
@@ -243,6 +338,50 @@ heap_init (grub_uint64_t addr, grub_uint64_t len, grub_memory_type_t type,
len = 0;
}
+ has_kernel_dump = check_kernel_dump (&upper_mem_limit);
+ if (has_kernel_dump)
+ {
+ grub_uint64_t lo_len = 0, hi_len = 0;
+
+ if (addr > upper_mem_limit || upper_mem_limit == (grub_uint64_t)~0)
+ return 0;
+
+ /* limit len to stay below upper_mem_limit */
+ if (addr < upper_mem_limit && (addr + len) > upper_mem_limit)
+ {
+ len = grub_min (len, upper_mem_limit - addr);
+ }
+
+ /* We can allocate below 640MB or above 768MB.
+ * Choose the bigger chunk below 640MB or above 768MB.
+ */
+ if (addr < 0x28000000)
+ {
+ lo_len = grub_min (len, 0x28000000 - addr);
+ }
+ if (addr + len > 0x30000000)
+ {
+ if (addr < 0x30000000)
+ hi_len = len - (0x30000000 - addr);
+ else
+ hi_len = len;
+ }
+
+ if (hi_len > lo_len)
+ {
+ len = hi_len;
+ if (addr < 0x30000000)
+ addr = 0x30000000;
+ }
+ else
+ {
+ len = lo_len;
+ }
+
+ if (len == 0)
+ return 0;
+ }
+
/* If this block contains 0x30000000 (768MB), do not claim below that.
Linux likes to claim memory at min(RMO top, 768MB) and works down
without reference to /memory/available. */

View File

@ -0,0 +1,34 @@
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Nicolas Frayer <nfrayer@redhat.com>
Date: Wed, 24 May 2023 11:22:47 +0200
Subject: [PATCH] util: Enable default kernel for updates
Several kernel variants can be installed on a system in parallel.
In order to allow the user to choose which kernel will be set to
default after an update, re-enable grub's usage of DEFAULTKERNEL as
set in /etc/sysconfig/kernel
Signed-off-by: Nicolas Frayer <nfrayer@redhat.com>
---
util/grub-get-kernel-settings.in | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/util/grub-get-kernel-settings.in b/util/grub-get-kernel-settings.in
index 7e87dfccc0e4..f71bc64360b0 100644
--- a/util/grub-get-kernel-settings.in
+++ b/util/grub-get-kernel-settings.in
@@ -68,6 +68,14 @@ if test -f /etc/sysconfig/kernel ; then
. /etc/sysconfig/kernel
fi
+GRUB_DEFAULT_KERNEL_TYPE=${DEFAULTKERNEL/-core/}
+if [ "$GRUB_DEFAULT_KERNEL_TYPE" != "kernel" ]; then
+ echo GRUB_NON_STANDARD_KERNEL=true
+ echo export GRUB_NON_STANDARD_KERNEL
+ GRUB_DEFAULT_KERNEL_TYPE=${GRUB_DEFAULT_KERNEL_TYPE/kernel-/}
+fi
+echo GRUB_DEFAULT_KERNEL_TYPE=$GRUB_DEFAULT_KERNEL_TYPE
+echo export GRUB_DEFAULT_KERNEL_TYPE
if [ "$MAKEDEBUG" = "yes" ]; then
echo GRUB_LINUX_MAKE_DEBUG=true
echo export GRUB_LINUX_MAKE_DEBUG

View File

@ -0,0 +1,150 @@
From 9ca4c3fe1c7dbd62e8ad6a23cb1b1fda695fdb44 Mon Sep 17 00:00:00 2001
From: Solar Designer <solar@openwall.com>
Date: Tue, 6 Feb 2024 21:39:41 +0100
Subject: [PATCH 1/3] grub-set-bootflag: Conservative partial fix for
CVE-2024-1048
Following up on CVE-2019-14865 and taking a fresh look at
grub2-set-bootflag now (through my work at CIQ on Rocky Linux), I saw some
other ways in which users could still abuse this little program:
1. After CVE-2019-14865 fix, grub2-set-bootflag no longer rewrites the
grubenv file in-place, but writes into a temporary file and renames it
over the original, checking for error returns from each call first.
This prevents the original file truncation vulnerability, but it can
leave the temporary file around if the program is killed before it can
rename or remove the file. There are still many ways to get the program
killed, such as through RLIMIT_FSIZE triggering SIGXFSZ (tested,
reliable) or by careful timing (tricky) of signals sent by process group
leader, pty, pre-scheduled timers, SIGXCPU (probably not an exhaustive
list). Invoking the program multiple times fills up /boot (or if /boot
is not separate, then it can fill up the root filesystem). Since the
files are tiny, the filesystem is likely to run out of free inodes
before it'd run out of blocks, but the effect is similar - can't create
new files after this point (but still can add data to existing files,
such as logs).
2. After CVE-2019-14865 fix, grub2-set-bootflag naively tries to protect
itself from signals by becoming full root. (This does protect it from
signals sent by the user directly to the PID, but e.g. "kill -9 -1" by
the user still works.) A side effect of such "protection" is that it's
possible to invoke more concurrent instances of grub2-set-bootflag than
the user's RLIMIT_NPROC would normally permit (as specified e.g. in
/etc/security/limits.conf, or say in Apache httpd's RLimitNPROC if
grub2-set-bootflag would be abused by a website script), thereby
exhausting system resources (e.g., bypassing RAM usage limit if
RLIMIT_AS was also set).
3. umask is inherited. Again, due to how the CVE-2019-14865 fix creates
a new file, and due to how mkstemp() works, this affects grubenv's new
file permissions. Luckily, mkstemp() forces them to be no more relaxed
than 0600, but the user ends up being able to set them e.g. to 0.
Luckily, at least in my testing GRUB still works fine even when the file
has such (lack of) permissions.
This commit deals with the abuses above as follows:
1. RLIMIT_FSIZE is pre-checked, so this specific way to get the process
killed should no longer work. However, this isn't a complete fix
because there are other ways to get the process killed after it has
created the temporary file.
The commit also fixes bug 1975892 ("RFE: grub2-set-bootflag should not
write the grubenv when the flag being written is already set") and
similar for "menu_show_once", which further reduces the abuse potential.
2. RLIMIT_NPROC bypass should be avoided by not becoming full root (aka
dropping the partial "kill protection").
3. A safe umask is set.
This is a partial fix (temporary files can still accumulate, but this is
harder to trigger).
While at it, this commit also fixes potential 1- or 2-byte over-read of
env[] if its content is malformed - this was not a security issue since the
grubenv file is trusted input, and the fix is just for robustness.
Signed-off-by: Solar Designer <solar@openwall.com>
---
util/grub-set-bootflag.c | 29 ++++++++++++++++-------------
1 file changed, 16 insertions(+), 13 deletions(-)
diff --git a/util/grub-set-bootflag.c b/util/grub-set-bootflag.c
index a85f11fceacb..5b932f76b6f4 100644
--- a/util/grub-set-bootflag.c
+++ b/util/grub-set-bootflag.c
@@ -32,6 +32,8 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <sys/stat.h>
+#include <sys/resource.h>
#define GRUBENV "/" GRUB_BOOT_DIR_NAME "/" GRUB_DIR_NAME "/" GRUB_ENVBLK_DEFCFG
#define GRUBENV_SIZE 1024
@@ -54,12 +56,17 @@ static void usage(void)
int main(int argc, char *argv[])
{
/* NOTE buf must be at least the longest bootflag length + 4 bytes */
- char env[GRUBENV_SIZE + 1], buf[64], *s;
+ char env[GRUBENV_SIZE + 1 + 2], buf[64], *s;
/* +1 for 0 termination, +6 for "XXXXXX" in tmp filename */
char env_filename[PATH_MAX + 1], tmp_filename[PATH_MAX + 6 + 1];
const char *bootflag;
int i, fd, len, ret;
FILE *f;
+ struct rlimit rlim;
+
+ if (getrlimit(RLIMIT_FSIZE, &rlim) || rlim.rlim_cur < GRUBENV_SIZE || rlim.rlim_max < GRUBENV_SIZE)
+ return 1;
+ umask(077);
if (argc != 2)
{
@@ -81,20 +88,11 @@ int main(int argc, char *argv[])
len = strlen (bootflag);
/*
- * Really become root. setuid avoids an user killing us, possibly leaking
- * the tmpfile. setgid avoids the new grubenv's gid being that of the user.
+ * setegid avoids the new grubenv's gid being that of the user.
*/
- ret = setuid(0);
- if (ret)
- {
- perror ("Error setuid(0) failed");
- return 1;
- }
-
- ret = setgid(0);
- if (ret)
+ if (setegid(0))
{
- perror ("Error setgid(0) failed");
+ perror ("Error setegid(0) failed");
return 1;
}
@@ -123,6 +121,9 @@ int main(int argc, char *argv[])
/* 0 terminate env */
env[GRUBENV_SIZE] = 0;
+ /* not a valid flag value */
+ env[GRUBENV_SIZE + 1] = 0;
+ env[GRUBENV_SIZE + 2] = 0;
if (strncmp (env, GRUB_ENVBLK_SIGNATURE, strlen (GRUB_ENVBLK_SIGNATURE)))
{
@@ -158,6 +159,8 @@ int main(int argc, char *argv[])
/* The grubenv is not 0 terminated, so memcpy the name + '=' , '1', '\n' */
snprintf(buf, sizeof(buf), "%s=1\n", bootflag);
+ if (!memcmp(s, buf, len + 3))
+ return 0; /* nothing to do */
memcpy(s, buf, len + 3);
--
2.43.0

View File

@ -0,0 +1,187 @@
From f4c7783c2b695794938748a6567e86456ed2314a Mon Sep 17 00:00:00 2001
From: Solar Designer <solar@openwall.com>
Date: Tue, 6 Feb 2024 21:56:21 +0100
Subject: [PATCH 2/3] grub-set-bootflag: More complete fix for CVE-2024-1048
Switch to per-user fixed temporary filenames along with a weird locking
mechanism, which is explained in source code comments. This is a more
complete fix than the previous commit (temporary files can't accumulate).
Unfortunately, it introduces new risks (by working on a temporary file
shared between the user's invocations), which are _hopefully_ avoided by
the patch's elaborate logic. I actually got it wrong at first, which
suggests that this logic is hard to reason about, and more errors or
omissions are possible. It also relies on the kernel's primitives' exact
semantics to a greater extent (nothing out of the ordinary, though).
Remaining issues that I think cannot reasonably be fixed without a
redesign (e.g., having per-flag files with nothing else in them) and
without introducing new issues:
A. A user can still revert a concurrent user's attempt of setting the
other flag - or of making other changes to grubenv by means other than
this program.
B. One leftover temporary file per user is still possible.
Signed-off-by: Solar Designer <solar@openwall.com>
---
util/grub-set-bootflag.c | 87 ++++++++++++++++++++++++++++++++++------
1 file changed, 75 insertions(+), 12 deletions(-)
diff --git a/util/grub-set-bootflag.c b/util/grub-set-bootflag.c
index 5b932f76b6f4..698b55a1ab93 100644
--- a/util/grub-set-bootflag.c
+++ b/util/grub-set-bootflag.c
@@ -32,6 +32,7 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <sys/file.h>
#include <sys/stat.h>
#include <sys/resource.h>
@@ -57,15 +58,12 @@ int main(int argc, char *argv[])
{
/* NOTE buf must be at least the longest bootflag length + 4 bytes */
char env[GRUBENV_SIZE + 1 + 2], buf[64], *s;
- /* +1 for 0 termination, +6 for "XXXXXX" in tmp filename */
- char env_filename[PATH_MAX + 1], tmp_filename[PATH_MAX + 6 + 1];
+ /* +1 for 0 termination, +11 for ".%u" in tmp filename */
+ char env_filename[PATH_MAX + 1], tmp_filename[PATH_MAX + 11 + 1];
const char *bootflag;
int i, fd, len, ret;
FILE *f;
- struct rlimit rlim;
- if (getrlimit(RLIMIT_FSIZE, &rlim) || rlim.rlim_cur < GRUBENV_SIZE || rlim.rlim_max < GRUBENV_SIZE)
- return 1;
umask(077);
if (argc != 2)
@@ -92,7 +90,7 @@ int main(int argc, char *argv[])
*/
if (setegid(0))
{
- perror ("Error setegid(0) failed");
+ perror ("setegid(0) failed");
return 1;
}
@@ -163,19 +161,82 @@ int main(int argc, char *argv[])
return 0; /* nothing to do */
memcpy(s, buf, len + 3);
+ struct rlimit rlim;
+ if (getrlimit(RLIMIT_FSIZE, &rlim) || rlim.rlim_cur < GRUBENV_SIZE || rlim.rlim_max < GRUBENV_SIZE)
+ {
+ fprintf (stderr, "Resource limits undetermined or too low\n");
+ return 1;
+ }
+
+ /*
+ * Here we work under the premise that we shouldn't write into the target
+ * file directly because we might not be able to have all of our changes
+ * written completely and atomically. That was CVE-2019-14865, known to
+ * have been triggerable via RLIMIT_FSIZE. While we've dealt with that
+ * specific attack via the check above, there may be other possibilities.
+ */
/*
* Create a tempfile for writing the new env. Use the canonicalized filename
* for the template so that the tmpfile is in the same dir / on same fs.
+ *
+ * We now use per-user fixed temporary filenames, so that a user cannot cause
+ * multiple files to accumulate.
+ *
+ * We don't use O_EXCL so that a stale temporary file doesn't prevent further
+ * usage of the program by the user.
*/
- snprintf(tmp_filename, sizeof(tmp_filename), "%sXXXXXX", env_filename);
- fd = mkstemp(tmp_filename);
+ snprintf(tmp_filename, sizeof(tmp_filename), "%s.%u", env_filename, getuid());
+ fd = open(tmp_filename, O_CREAT | O_WRONLY, 0600);
if (fd == -1)
{
perror ("Creating tmpfile failed");
return 1;
}
+ /*
+ * The lock prevents the same user from reaching further steps ending in
+ * rename() concurrently, in which case the temporary file only partially
+ * written by one invocation could be renamed to the target file by another.
+ *
+ * The lock also guards the slow fsync() from concurrent calls. After the
+ * first time that and the rename() complete, further invocations for the
+ * same flag become no-ops.
+ *
+ * We lock the temporary file rather than the target file because locking the
+ * latter would allow any user having SIGSTOP'ed their process to make all
+ * other users' invocations fail (or lock up if we'd use blocking mode).
+ *
+ * We use non-blocking mode (LOCK_NB) because the lock having been taken by
+ * another process implies that the other process would normally have already
+ * renamed the file to target by the time it releases the lock (and we could
+ * acquire it), so we'd be working directly on the target if we proceeded,
+ * which is undesirable, and we'd kind of fail on the already-done rename.
+ */
+ if (flock(fd, LOCK_EX | LOCK_NB))
+ {
+ perror ("Locking tmpfile failed");
+ return 1;
+ }
+
+ /*
+ * Deal with the potential that another invocation proceeded all the way to
+ * rename() and process exit while we were between open() and flock().
+ */
+ {
+ struct stat st1, st2;
+ if (fstat(fd, &st1) || stat(tmp_filename, &st2))
+ {
+ perror ("stat of tmpfile failed");
+ return 1;
+ }
+ if (st1.st_dev != st2.st_dev || st1.st_ino != st2.st_ino)
+ {
+ fprintf (stderr, "Another invocation won race\n");
+ return 1;
+ }
+ }
+
f = fdopen (fd, "w");
if (!f)
{
@@ -200,23 +261,25 @@ int main(int argc, char *argv[])
return 1;
}
- ret = fsync (fileno (f));
+ ret = ftruncate (fileno (f), GRUBENV_SIZE);
if (ret)
{
- perror ("Error syncing tmpfile");
+ perror ("Error truncating tmpfile");
unlink(tmp_filename);
return 1;
}
- ret = fclose (f);
+ ret = fsync (fileno (f));
if (ret)
{
- perror ("Error closing tmpfile");
+ perror ("Error syncing tmpfile");
unlink(tmp_filename);
return 1;
}
/*
+ * We must not close the file before rename() as that would remove the lock.
+ *
* And finally rename the tmpfile with the new env over the old env, the
* linux kernel guarantees that this is atomic (from a syscall pov).
*/
--
2.43.0

View File

@ -0,0 +1,39 @@
From a7192a650c1e94221a86b49f5132fb47a4dda6ea Mon Sep 17 00:00:00 2001
From: Solar Designer <solar@openwall.com>
Date: Tue, 6 Feb 2024 22:05:45 +0100
Subject: [PATCH 3/3] grub-set-bootflag: Exit calmly when not running as root
Exit calmly when not installed SUID root and invoked by non-root. This
allows installing user/grub-boot-success.service unconditionally while
supporting non-SUID installation of the program for some limited usage.
Signed-off-by: Solar Designer <solar@openwall.com>
---
util/grub-set-bootflag.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/util/grub-set-bootflag.c b/util/grub-set-bootflag.c
index 698b55a1ab93..a51805fa8cec 100644
--- a/util/grub-set-bootflag.c
+++ b/util/grub-set-bootflag.c
@@ -85,6 +85,17 @@ int main(int argc, char *argv[])
bootflag = bootflags[i];
len = strlen (bootflag);
+ /*
+ * Exit calmly when not installed SUID root and invoked by non-root. This
+ * allows installing user/grub-boot-success.service unconditionally while
+ * supporting non-SUID installation of the program for some limited usage.
+ */
+ if (geteuid())
+ {
+ printf ("grub-set-bootflag not running as root, no action taken\n");
+ return 0;
+ }
+
/*
* setegid avoids the new grubenv's gid being that of the user.
*/
--
2.43.0

View File

@ -0,0 +1,93 @@
From 43651027d24e62a7a463254165e1e46e42aecdea Mon Sep 17 00:00:00 2001
From: Maxim Suhanov <dfirblog@gmail.com>
Date: Mon, 28 Aug 2023 16:31:57 +0300
Subject: [PATCH 1/6] fs/ntfs: Fix an OOB write when parsing the
$ATTRIBUTE_LIST attribute for the $MFT file
When parsing an extremely fragmented $MFT file, i.e., the file described
using the $ATTRIBUTE_LIST attribute, current NTFS code will reuse a buffer
containing bytes read from the underlying drive to store sector numbers,
which are consumed later to read data from these sectors into another buffer.
These sectors numbers, two 32-bit integers, are always stored at predefined
offsets, 0x10 and 0x14, relative to first byte of the selected entry within
the $ATTRIBUTE_LIST attribute. Usually, this won't cause any problem.
However, when parsing a specially-crafted file system image, this may cause
the NTFS code to write these integers beyond the buffer boundary, likely
causing the GRUB memory allocator to misbehave or fail. These integers contain
values which are controlled by on-disk structures of the NTFS file system.
Such modification and resulting misbehavior may touch a memory range not
assigned to the GRUB and owned by firmware or another EFI application/driver.
This fix introduces checks to ensure that these sector numbers are never
written beyond the boundary.
Fixes: CVE-2023-4692
Reported-by: Maxim Suhanov <dfirblog@gmail.com>
Signed-off-by: Maxim Suhanov <dfirblog@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/fs/ntfs.c | 18 +++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)
diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c
index bbdbe24ada83..c3c4db117bba 100644
--- a/grub-core/fs/ntfs.c
+++ b/grub-core/fs/ntfs.c
@@ -184,7 +184,7 @@ find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr)
}
if (at->attr_end)
{
- grub_uint8_t *pa;
+ grub_uint8_t *pa, *pa_end;
at->emft_buf = grub_malloc (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR);
if (at->emft_buf == NULL)
@@ -209,11 +209,13 @@ find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr)
}
at->attr_nxt = at->edat_buf;
at->attr_end = at->edat_buf + u32at (pa, 0x30);
+ pa_end = at->edat_buf + n;
}
else
{
at->attr_nxt = at->attr_end + u16at (pa, 0x14);
at->attr_end = at->attr_end + u32at (pa, 4);
+ pa_end = at->mft->buf + (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR);
}
at->flags |= GRUB_NTFS_AF_ALST;
while (at->attr_nxt < at->attr_end)
@@ -230,6 +232,13 @@ find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr)
at->flags |= GRUB_NTFS_AF_GPOS;
at->attr_cur = at->attr_nxt;
pa = at->attr_cur;
+
+ if ((pa >= pa_end) || (pa_end - pa < 0x18))
+ {
+ grub_error (GRUB_ERR_BAD_FS, "can\'t parse attribute list");
+ return NULL;
+ }
+
grub_set_unaligned32 ((char *) pa + 0x10,
grub_cpu_to_le32 (at->mft->data->mft_start));
grub_set_unaligned32 ((char *) pa + 0x14,
@@ -240,6 +249,13 @@ find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr)
{
if (*pa != attr)
break;
+
+ if ((pa >= pa_end) || (pa_end - pa < 0x18))
+ {
+ grub_error (GRUB_ERR_BAD_FS, "can\'t parse attribute list");
+ return NULL;
+ }
+
if (read_attr
(at, pa + 0x10,
u32at (pa, 0x10) * (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR),
--
2.43.0

View File

@ -0,0 +1,58 @@
From 0ed2458cc4eff6d9a9199527e2a0b6d445802f94 Mon Sep 17 00:00:00 2001
From: Maxim Suhanov <dfirblog@gmail.com>
Date: Mon, 28 Aug 2023 16:32:33 +0300
Subject: [PATCH 2/6] fs/ntfs: Fix an OOB read when reading data from the
resident $DATA attribute
When reading a file containing resident data, i.e., the file data is stored in
the $DATA attribute within the NTFS file record, not in external clusters,
there are no checks that this resident data actually fits the corresponding
file record segment.
When parsing a specially-crafted file system image, the current NTFS code will
read the file data from an arbitrary, attacker-chosen memory offset and of
arbitrary, attacker-chosen length.
This allows an attacker to display arbitrary chunks of memory, which could
contain sensitive information like password hashes or even plain-text,
obfuscated passwords from BS EFI variables.
This fix implements a check to ensure that resident data is read from the
corresponding file record segment only.
Fixes: CVE-2023-4693
Reported-by: Maxim Suhanov <dfirblog@gmail.com>
Signed-off-by: Maxim Suhanov <dfirblog@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/fs/ntfs.c | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c
index c3c4db117bba..a68e173d8285 100644
--- a/grub-core/fs/ntfs.c
+++ b/grub-core/fs/ntfs.c
@@ -401,7 +401,18 @@ read_data (struct grub_ntfs_attr *at, grub_uint8_t *pa, grub_uint8_t *dest,
{
if (ofs + len > u32at (pa, 0x10))
return grub_error (GRUB_ERR_BAD_FS, "read out of range");
- grub_memcpy (dest, pa + u32at (pa, 0x14) + ofs, len);
+
+ if (u32at (pa, 0x10) > (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR))
+ return grub_error (GRUB_ERR_BAD_FS, "resident attribute too large");
+
+ if (pa >= at->mft->buf + (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR))
+ return grub_error (GRUB_ERR_BAD_FS, "resident attribute out of range");
+
+ if (u16at (pa, 0x14) + u32at (pa, 0x10) >
+ (grub_addr_t) at->mft->buf + (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR) - (grub_addr_t) pa)
+ return grub_error (GRUB_ERR_BAD_FS, "resident attribute out of range");
+
+ grub_memcpy (dest, pa + u16at (pa, 0x14) + ofs, len);
return 0;
}
--
2.43.0

View File

@ -0,0 +1,73 @@
From 7e5f031a6a6a3decc2360a7b0c71abbe598e7354 Mon Sep 17 00:00:00 2001
From: Maxim Suhanov <dfirblog@gmail.com>
Date: Mon, 28 Aug 2023 16:33:17 +0300
Subject: [PATCH 3/6] fs/ntfs: Fix an OOB read when parsing directory entries
from resident and non-resident index attributes
This fix introduces checks to ensure that index entries are never read
beyond the corresponding directory index.
The lack of this check is a minor issue, likely not exploitable in any way.
Reported-by: Maxim Suhanov <dfirblog@gmail.com>
Signed-off-by: Maxim Suhanov <dfirblog@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/fs/ntfs.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c
index a68e173d8285..2d78b96e19fb 100644
--- a/grub-core/fs/ntfs.c
+++ b/grub-core/fs/ntfs.c
@@ -599,7 +599,7 @@ get_utf8 (grub_uint8_t *in, grub_size_t len)
}
static int
-list_file (struct grub_ntfs_file *diro, grub_uint8_t *pos,
+list_file (struct grub_ntfs_file *diro, grub_uint8_t *pos, grub_uint8_t *end_pos,
grub_fshelp_iterate_dir_hook_t hook, void *hook_data)
{
grub_uint8_t *np;
@@ -610,6 +610,9 @@ list_file (struct grub_ntfs_file *diro, grub_uint8_t *pos,
grub_uint8_t namespace;
char *ustr;
+ if ((pos >= end_pos) || (end_pos - pos < 0x52))
+ break;
+
if (pos[0xC] & 2) /* end signature */
break;
@@ -617,6 +620,9 @@ list_file (struct grub_ntfs_file *diro, grub_uint8_t *pos,
ns = *(np++);
namespace = *(np++);
+ if (2 * ns > end_pos - pos - 0x52)
+ break;
+
/*
* Ignore files in DOS namespace, as they will reappear as Win32
* names.
@@ -806,7 +812,9 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir,
}
cur_pos += 0x10; /* Skip index root */
- ret = list_file (mft, cur_pos + u16at (cur_pos, 0), hook, hook_data);
+ ret = list_file (mft, cur_pos + u16at (cur_pos, 0),
+ at->mft->buf + (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR),
+ hook, hook_data);
if (ret)
goto done;
@@ -893,6 +901,7 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir,
(const grub_uint8_t *) "INDX")))
goto done;
ret = list_file (mft, &indx[0x18 + u16at (indx, 0x18)],
+ indx + (mft->data->idx_size << GRUB_NTFS_BLK_SHR),
hook, hook_data);
if (ret)
goto done;
--
2.43.0

View File

@ -0,0 +1,51 @@
From 7a5a116739fa6d8a625da7d6b9272c9a2462f967 Mon Sep 17 00:00:00 2001
From: Maxim Suhanov <dfirblog@gmail.com>
Date: Mon, 28 Aug 2023 16:33:44 +0300
Subject: [PATCH 4/6] fs/ntfs: Fix an OOB read when parsing bitmaps for index
attributes
This fix introduces checks to ensure that bitmaps for directory indices
are never read beyond their actual sizes.
The lack of this check is a minor issue, likely not exploitable in any way.
Reported-by: Maxim Suhanov <dfirblog@gmail.com>
Signed-off-by: Maxim Suhanov <dfirblog@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/fs/ntfs.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c
index 2d78b96e19fb..bb70c89fb803 100644
--- a/grub-core/fs/ntfs.c
+++ b/grub-core/fs/ntfs.c
@@ -843,6 +843,25 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir,
if (is_resident)
{
+ if (bitmap_len > (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR))
+ {
+ grub_error (GRUB_ERR_BAD_FS, "resident bitmap too large");
+ goto done;
+ }
+
+ if (cur_pos >= at->mft->buf + (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR))
+ {
+ grub_error (GRUB_ERR_BAD_FS, "resident bitmap out of range");
+ goto done;
+ }
+
+ if (u16at (cur_pos, 0x14) + u32at (cur_pos, 0x10) >
+ (grub_addr_t) at->mft->buf + (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR) - (grub_addr_t) cur_pos)
+ {
+ grub_error (GRUB_ERR_BAD_FS, "resident bitmap out of range");
+ goto done;
+ }
+
grub_memcpy (bmp, cur_pos + u16at (cur_pos, 0x14),
bitmap_len);
}
--
2.43.0

View File

@ -0,0 +1,61 @@
From 1fe82c41e070385e273d7bb1cfb482627a3c28e8 Mon Sep 17 00:00:00 2001
From: Maxim Suhanov <dfirblog@gmail.com>
Date: Mon, 28 Aug 2023 16:38:19 +0300
Subject: [PATCH 5/6] fs/ntfs: Fix an OOB read when parsing a volume label
This fix introduces checks to ensure that an NTFS volume label is always
read from the corresponding file record segment.
The current NTFS code allows the volume label string to be read from an
arbitrary, attacker-chosen memory location. However, the bytes read are
always treated as UTF-16LE. So, the final string displayed is mostly
unreadable and it can't be easily converted back to raw bytes.
The lack of this check is a minor issue, likely not causing a significant
data leak.
Reported-by: Maxim Suhanov <dfirblog@gmail.com>
Signed-off-by: Maxim Suhanov <dfirblog@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/fs/ntfs.c | 18 +++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)
diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c
index bb70c89fb803..ff5e3740f0dd 100644
--- a/grub-core/fs/ntfs.c
+++ b/grub-core/fs/ntfs.c
@@ -1213,13 +1213,29 @@ grub_ntfs_label (grub_device_t device, char **label)
init_attr (&mft->attr, mft);
pa = find_attr (&mft->attr, GRUB_NTFS_AT_VOLUME_NAME);
+
+ if (pa >= mft->buf + (mft->data->mft_size << GRUB_NTFS_BLK_SHR))
+ {
+ grub_error (GRUB_ERR_BAD_FS, "can\'t parse volume label");
+ goto fail;
+ }
+
+ if (mft->buf + (mft->data->mft_size << GRUB_NTFS_BLK_SHR) - pa < 0x16)
+ {
+ grub_error (GRUB_ERR_BAD_FS, "can\'t parse volume label");
+ goto fail;
+ }
+
if ((pa) && (pa[8] == 0) && (u32at (pa, 0x10)))
{
int len;
len = u32at (pa, 0x10) / 2;
pa += u16at (pa, 0x14);
- *label = get_utf8 (pa, len);
+ if (mft->buf + (mft->data->mft_size << GRUB_NTFS_BLK_SHR) - pa >= 2 * len)
+ *label = get_utf8 (pa, len);
+ else
+ grub_error (GRUB_ERR_BAD_FS, "can\'t parse volume label");
}
fail:
--
2.43.0

View File

@ -0,0 +1,159 @@
From e58b870ff926415e23fc386af41ff81b2f588763 Mon Sep 17 00:00:00 2001
From: Maxim Suhanov <dfirblog@gmail.com>
Date: Mon, 28 Aug 2023 16:40:07 +0300
Subject: [PATCH 6/6] fs/ntfs: Make code more readable
Move some calls used to access NTFS attribute header fields into
functions with human-readable names.
Suggested-by: Daniel Kiper <daniel.kiper@oracle.com>
Signed-off-by: Maxim Suhanov <dfirblog@gmail.com>
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
---
grub-core/fs/ntfs.c | 48 +++++++++++++++++++++++++++++++--------------
1 file changed, 33 insertions(+), 15 deletions(-)
diff --git a/grub-core/fs/ntfs.c b/grub-core/fs/ntfs.c
index ff5e3740f0dd..de435aa14d85 100644
--- a/grub-core/fs/ntfs.c
+++ b/grub-core/fs/ntfs.c
@@ -52,6 +52,24 @@ u64at (void *ptr, grub_size_t ofs)
return grub_le_to_cpu64 (grub_get_unaligned64 ((char *) ptr + ofs));
}
+static grub_uint16_t
+first_attr_off (void *mft_buf_ptr)
+{
+ return u16at (mft_buf_ptr, 0x14);
+}
+
+static grub_uint16_t
+res_attr_data_off (void *res_attr_ptr)
+{
+ return u16at (res_attr_ptr, 0x14);
+}
+
+static grub_uint32_t
+res_attr_data_len (void *res_attr_ptr)
+{
+ return u32at (res_attr_ptr, 0x10);
+}
+
grub_ntfscomp_func_t grub_ntfscomp_func;
static grub_err_t
@@ -106,7 +124,7 @@ init_attr (struct grub_ntfs_attr *at, struct grub_ntfs_file *mft)
{
at->mft = mft;
at->flags = (mft == &mft->data->mmft) ? GRUB_NTFS_AF_MMFT : 0;
- at->attr_nxt = mft->buf + u16at (mft->buf, 0x14);
+ at->attr_nxt = mft->buf + first_attr_off (mft->buf);
at->attr_end = at->emft_buf = at->edat_buf = at->sbuf = NULL;
}
@@ -154,7 +172,7 @@ find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr)
return NULL;
}
- new_pos = &at->emft_buf[u16at (at->emft_buf, 0x14)];
+ new_pos = &at->emft_buf[first_attr_off (at->emft_buf)];
while (*new_pos != 0xFF)
{
if ((*new_pos == *at->attr_cur)
@@ -213,7 +231,7 @@ find_attr (struct grub_ntfs_attr *at, grub_uint8_t attr)
}
else
{
- at->attr_nxt = at->attr_end + u16at (pa, 0x14);
+ at->attr_nxt = at->attr_end + res_attr_data_off (pa);
at->attr_end = at->attr_end + u32at (pa, 4);
pa_end = at->mft->buf + (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR);
}
@@ -399,20 +417,20 @@ read_data (struct grub_ntfs_attr *at, grub_uint8_t *pa, grub_uint8_t *dest,
if (pa[8] == 0)
{
- if (ofs + len > u32at (pa, 0x10))
+ if (ofs + len > res_attr_data_len (pa))
return grub_error (GRUB_ERR_BAD_FS, "read out of range");
- if (u32at (pa, 0x10) > (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR))
+ if (res_attr_data_len (pa) > (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR))
return grub_error (GRUB_ERR_BAD_FS, "resident attribute too large");
if (pa >= at->mft->buf + (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR))
return grub_error (GRUB_ERR_BAD_FS, "resident attribute out of range");
- if (u16at (pa, 0x14) + u32at (pa, 0x10) >
+ if (res_attr_data_off (pa) + res_attr_data_len (pa) >
(grub_addr_t) at->mft->buf + (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR) - (grub_addr_t) pa)
return grub_error (GRUB_ERR_BAD_FS, "resident attribute out of range");
- grub_memcpy (dest, pa + u16at (pa, 0x14) + ofs, len);
+ grub_memcpy (dest, pa + res_attr_data_off (pa) + ofs, len);
return 0;
}
@@ -556,7 +574,7 @@ init_file (struct grub_ntfs_file *mft, grub_uint64_t mftno)
(unsigned long long) mftno);
if (!pa[8])
- mft->size = u32at (pa, 0x10);
+ mft->size = res_attr_data_len (pa);
else
mft->size = u64at (pa, 0x30);
@@ -805,7 +823,7 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir,
(u32at (cur_pos, 0x18) != 0x490024) ||
(u32at (cur_pos, 0x1C) != 0x300033))
continue;
- cur_pos += u16at (cur_pos, 0x14);
+ cur_pos += res_attr_data_off (cur_pos);
if (*cur_pos != 0x30) /* Not filename index */
continue;
break;
@@ -834,7 +852,7 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir,
{
int is_resident = (cur_pos[8] == 0);
- bitmap_len = ((is_resident) ? u32at (cur_pos, 0x10) :
+ bitmap_len = ((is_resident) ? res_attr_data_len (cur_pos) :
u32at (cur_pos, 0x28));
bmp = grub_malloc (bitmap_len);
@@ -855,14 +873,14 @@ grub_ntfs_iterate_dir (grub_fshelp_node_t dir,
goto done;
}
- if (u16at (cur_pos, 0x14) + u32at (cur_pos, 0x10) >
+ if (res_attr_data_off (cur_pos) + res_attr_data_len (cur_pos) >
(grub_addr_t) at->mft->buf + (at->mft->data->mft_size << GRUB_NTFS_BLK_SHR) - (grub_addr_t) cur_pos)
{
grub_error (GRUB_ERR_BAD_FS, "resident bitmap out of range");
goto done;
}
- grub_memcpy (bmp, cur_pos + u16at (cur_pos, 0x14),
+ grub_memcpy (bmp, cur_pos + res_attr_data_off (cur_pos),
bitmap_len);
}
else
@@ -1226,12 +1244,12 @@ grub_ntfs_label (grub_device_t device, char **label)
goto fail;
}
- if ((pa) && (pa[8] == 0) && (u32at (pa, 0x10)))
+ if ((pa) && (pa[8] == 0) && (res_attr_data_len (pa)))
{
int len;
- len = u32at (pa, 0x10) / 2;
- pa += u16at (pa, 0x14);
+ len = res_attr_data_len (pa) / 2;
+ pa += res_attr_data_off (pa);
if (mft->buf + (mft->data->mft_size << GRUB_NTFS_BLK_SHR) - pa >= 2 * len)
*label = get_utf8 (pa, len);
else
--
2.43.0

View File

@ -109,7 +109,11 @@ case "$COMMAND" in
sed -i -e "s,^initrd.*,initrd ${BOOTPREFIX}${INITRD},g" "${BLS_TARGET}"
fi
if [[ "$KERNEL_VERSION" == *\+* ]] && [ "x$GRUB_DEFAULT_TO_DEBUG" != "xtrue" ]; then
if ( [[ "$KERNEL_VERSION" != *${GRUB_DEFAULT_KERNEL_TYPE}* ]] && \
[ "x$GRUB_NON_STANDARD_KERNEL" == "xtrue" ] ) || \
( echo "$KERNEL_VERSION" | grep -E -q "64k|auto|rt|uki" && \
[ "x$GRUB_NON_STANDARD_KERNEL" != "xtrue" ] ) || \
( [[ "$KERNEL_VERSION" == *debug* ]] && [ "x$GRUB_DEFAULT_TO_DEBUG" != "xtrue" ] ); then
GRUB_UPDATE_DEFAULT_KERNEL=false
fi

Binary file not shown.

View File

@ -285,7 +285,13 @@ Requires: %{name}-common = %{evr} \
Requires: %{name}-tools-minimal >= %{evr} \
Requires: %{name}-tools-extra = %{evr} \
Requires: %{name}-tools = %{evr} \
Requires: %{efi_esp_dir}/shim%%(echo %{1} | cut -d- -f2).efi \
Provides: %{name}-efi = %{evr} \
Provides: almalinux(grub2-sig-key) = 202303 \
%{expand:%%ifarch x86_64 \
Conflicts: shim-x64 <= 15.6-1.el8.alma \
Conflicts: shim-ia32 <= 15.6-1.el8.alma \
%%endif} \
%{?legacy_provides:Provides: %{name} = %{evr}} \
%{-o:Obsoletes: %{name}-efi < %{evr}} \
\
@ -540,7 +546,7 @@ install -D -m 700 unicode.pf2 \\\
$RPM_BUILD_ROOT%{efi_esp_dir}/fonts/unicode.pf2 \
${RPM_BUILD_ROOT}/%{_bindir}/%{name}-editenv \\\
${RPM_BUILD_ROOT}%{efi_esp_dir}/grubenv create \
ln -sf ../efi/EFI/%{efi_vendor}/grubenv \\\
ln -sf ../efi/EFI/%{efidir}/grubenv \\\
$RPM_BUILD_ROOT/boot/grub2/grubenv \
cd .. \
%{nil}

View File

@ -573,3 +573,18 @@ Patch0572: 0572-font-Assign-null_font-to-glyphs-in-ascii_font_glyph.patch
Patch0573: 0573-normal-charset-Fix-an-integer-overflow-in-grub_unico.patch
Patch0574: 0574-Enable-TDX-measurement-to-RTMR-register.patch
Patch0575: 0575-Enable-shared-processor-mode-in-vector-5.patch
Patch0576: 0576-efi-http-change-uint32_t-to-uintn_t-for-grub_efi_htt.patch
Patch0577: 0577-ieee1275-Converting-plain-numbers-to-constants-in-Ve.patch
Patch0578: 0578-ieee1275-extended-support-in-options-vector5.patch
Patch0579: 0579-Regenerate-kernelopts-if-missing-on-ppc.patch
Patch0580: 0580-kern-ieee1275-init-ppc64-Restrict-high-memory-in-pre.patch
Patch0581: 0581-util-Enable-default-kernel-for-updates.patch
Patch0582: 0582-grub-set-bootflag-Conservative-partial-fix-for-CVE-2.patch
Patch0583: 0583-grub-set-bootflag-More-complete-fix-for-CVE-2024-104.patch
Patch0584: 0584-grub-set-bootflag-Exit-calmly-when-not-running-as-ro.patch
Patch0585: 0585-fs-ntfs-Fix-an-OOB-write-when-parsing-the-ATTRIBUTE_.patch
Patch0586: 0586-fs-ntfs-Fix-an-OOB-read-when-reading-data-from-the-r.patch
Patch0587: 0587-fs-ntfs-Fix-an-OOB-read-when-parsing-directory-entri.patch
Patch0588: 0588-fs-ntfs-Fix-an-OOB-read-when-parsing-bitmaps-for-ind.patch
Patch0589: 0589-fs-ntfs-Fix-an-OOB-read-when-parsing-a-volume-label.patch
Patch0590: 0590-fs-ntfs-Make-code-more-readable.patch

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,3 +1,4 @@
sbat,1,SBAT Version,sbat,1,https://github.com/rhboot/shim/blob/main/SBAT.md
grub,3,Free Software Foundation,grub,@@VERSION@@,https//www.gnu.org/software/grub/
grub.rh,2,Red Hat,grub2,@@VERSION_RELEASE@@,mailto:secalert@redhat.com
grub.rh,2,Red Hat,grub2,@@RHEL_VERSION_RELEASE@@,mailto:secalert@redhat.com
grub.almalinux,2,AlmaLinux,grub2,@@VERSION_RELEASE@@,mail:security@almalinux.org

View File

@ -1,3 +1,7 @@
%global efi_vendor almalinux
%global efidir almalinux
%global efi_esp_dir /boot/efi/EFI/%{efidir}
%undefine _hardened_build
%global tarversion 2.02
@ -7,7 +11,7 @@
Name: grub2
Epoch: 1
Version: 2.02
Release: 148%{?dist}
Release: 156%{?dist}.alma.1
Summary: Bootloader with support for Linux, Multiboot and more
Group: System Environment/Base
License: GPLv3+
@ -24,31 +28,29 @@ Source6: gitignore
Source8: strtoull_test.c
Source9: 20-grub.install
Source12: 99-grub-mkconfig.install
Source13: redhatsecurebootca3.cer
Source14: redhatsecureboot301.cer
Source15: redhatsecurebootca5.cer
Source16: redhatsecureboot502.cer
Source17: redhatsecureboot601.cer
Source18: redhatsecureboot701.cer
Source13: almalinuxsecurebootca0.cer
Source19: sbat.csv.in
%include %{SOURCE1}
%if 0%{with_efi_arch}
%define old_sb_ca %{SOURCE13}
%define old_sb_cer %{SOURCE14}
%define old_sb_key redhatsecureboot301
%define sb_ca %{SOURCE15}
%define sb_cer %{SOURCE16}
%define sb_key redhatsecureboot502
%define old_sb_cer %{SOURCE13}
%define old_sb_key almalinuxsecurebootca0
%define sb_ca %{SOURCE13}
%define sb_cer %{SOURCE13}
%define sb_key almalinuxsecurebootca0
%endif
%ifarch ppc64le
%define old_sb_cer %{SOURCE17}
%define sb_cer %{SOURCE18}
%define sb_key redhatsecureboot702
%define old_sb_cer %{SOURCE13}
%define sb_cer %{SOURCE13}
%define sb_key almalinuxsecurebootca0
%endif
# AlmaLinux: keep upstream EVR for RHEL SBAT entry
%define rhel_version_release $(echo %{version}-%{release} | sed 's/\.alma.*//')
# generate with do-rebase
%include %{SOURCE2}
@ -166,7 +168,7 @@ This subpackage provides tools for support of all platforms.
mkdir grub-%{grubefiarch}-%{tarversion}
grep -A100000 '# stuff "make" creates' .gitignore > grub-%{grubefiarch}-%{tarversion}/.gitignore
cp %{SOURCE4} grub-%{grubefiarch}-%{tarversion}/unifont.pcf.gz
sed -e "s,@@VERSION@@,%{version},g" -e "s,@@VERSION_RELEASE@@,%{version}-%{release},g" \
sed -e "s,@@VERSION@@,%{version},g" -e "s,@@VERSION_RELEASE@@,%{version}-%{release},g" -e "s,@@RHEL_VERSION_RELEASE@@,%{rhel_version_release},g" \
%{SOURCE19} > grub-%{grubefiarch}-%{tarversion}/sbat.csv
git add grub-%{grubefiarch}-%{tarversion}
%endif
@ -341,6 +343,20 @@ if [ "$1" = 0 ]; then
/sbin/install-info --delete --info-dir=%{_infodir} %{_infodir}/%{name}-dev.info.gz || :
fi
%if 0%{with_efi_arch}
%posttrans %{package_arch}
if [ -d /sys/firmware/efi ] && [ ! -f %{efi_esp_dir}/grub.cfg ]; then
grub2-mkconfig -o %{efi_esp_dir}/grub.cfg || :
fi
%endif
%if 0%{with_alt_efi_arch}
%posttrans %{alt_package_arch}
if [ -d /sys/firmware/efi ] && [ ! -f %{efi_esp_dir}/grub.cfg ]; then
grub2-mkconfig -o %{efi_esp_dir}/grub.cfg || :
fi
%endif
%files common -f grub.lang
%dir %{_libdir}/grub/
%dir %{_datarootdir}/grub/
@ -510,6 +526,44 @@ fi
%endif
%changelog
* Wed Apr 10 2024 Andrew Lukoshko <alukoshko@almalinux.org> - 2.02-156.alma.1
- Debrand for AlmaLinux
* Tue Feb 20 2024 Nicolas Frayer <nfrayer@redhat.com> - 2.02-156
- fs/ntfs: OOB write fix
- (CVE-2023-4692)
- Resolves: #RHEL-11566
* Thu Feb 8 2024 Nicolas Frayer <nfrayer@redhat.com> - 2.06-155
- grub-set-bootflag: Fix for CVE-2024-1048
- (CVE-2024-1048)
- Resolves: #RHEL-20746
* Mon Nov 27 2023 Nicolas Frayer <nfrayer@redhat.com> - 2.02-154
- Missing install script for previous commit
- Related: #RHEL-4343
* Fri Nov 24 2023 Nicolas Frayer <nfrayer@redhat.com> - 2.02-153
- util: Enable default kernel for updates
- Resolves: #RHEL-4343
* Fri Oct 20 2023 Nicolas Frayer <nfrayer@redhat.com> - 2.02-152
- kern/ieee1275/init: ppc64: Restrict high memory in presence
of fadump
- Resolves: #RHEL-14283
* Mon Aug 28 2023 Nicolas Frayer <nfrayer@redhat.com> - 2.02-151
- util: Regenerate kernelopts if missing on ppc
- Resolves: #2051889
* Fri Jun 16 2023 Nicolas Frayer <nfrayer@redhat.com> - 2.02-150
- kern/ieee1275/init: sync vec5 patchset with upstream
- Resolves: #2172111
* Wed Jun 14 2023 Nicolas Frayer <nfrayer@redhat.com> - 2.02-149
- efi/http: change uint32_t to uintn_t for grub_efi_http_message_t
- Resolves: #2178388
* Mon Feb 06 2023 Robbie Harwood <rharwood@redhat.com> - 2.02-148
- ppc64le: cas5, take 3
- Resolves: #2139508