!49 update version to 15.6

From: @jinlun123123 
Reviewed-by: @huangzq6, @HuaxinLuGitee 
Signed-off-by: @HuaxinLuGitee
This commit is contained in:
openeuler-ci-bot 2022-11-04 06:42:13 +00:00 committed by Gitee
commit c1286d3e83
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
17 changed files with 17 additions and 1367 deletions

View File

@ -1,62 +0,0 @@
From e99bdbb827a50cde019393d3ca1e89397db221a7 Mon Sep 17 00:00:00 2001
From: Chris Coulson <chris.coulson@canonical.com>
Date: Tue, 3 May 2022 15:41:00 +0200
Subject: [PATCH] pe: Fix a buffer overflow when SizeOfRawData > VirtualSize
During image loading, the size of the destination buffer for the image
is determined by the SizeOfImage field in the optional header. The start
and end virtual addresses of each section, as determined by each section's
VirtualAddress and VirtualSize fields, are bounds checked against the
allocated buffer. However, the amount of data copied to the destination
buffer is determined by the section's SizeOfRawData filed. If this is
larger than the VirtualSize, then the copy can overflow the destination
buffer.
Fix this by limiting the amount of data to copy to the section's
VirtualSize. In the case where a section has SizeOfRawData > VirtualSize,
the excess data is discarded.
This fixes CVE-2022-28737
Signed-off-by: Chris Coulson <chris.coulson@canonical.com>
---
pe.c | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/pe.c b/pe.c
index 5d0c6b0..1eb3f59 100644
--- a/pe.c
+++ b/pe.c
@@ -1089,6 +1089,7 @@ handle_image (void *data, unsigned int datasize,
int i;
EFI_IMAGE_SECTION_HEADER *Section;
char *base, *end;
+ UINT32 size;
PE_COFF_LOADER_IMAGE_CONTEXT context;
unsigned int alignment, alloc_size;
int found_entry_point = 0;
@@ -1274,13 +1275,15 @@ handle_image (void *data, unsigned int datasize,
return EFI_UNSUPPORTED;
}
- if (Section->SizeOfRawData > 0)
- CopyMem(base, data + Section->PointerToRawData,
- Section->SizeOfRawData);
+ size = Section->Misc.VirtualSize;
+ if (size > Section->SizeOfRawData)
+ size = Section->SizeOfRawData;
- if (Section->SizeOfRawData < Section->Misc.VirtualSize)
- ZeroMem(base + Section->SizeOfRawData,
- Section->Misc.VirtualSize - Section->SizeOfRawData);
+ if (size > 0)
+ CopyMem(base, data + Section->PointerToRawData, size);
+
+ if (size < Section->Misc.VirtualSize)
+ ZeroMem(base + size, Section->Misc.VirtualSize - size);
}
}
--
2.27.0

View File

@ -1,78 +0,0 @@
From 5a82d7973656c68f006aac1ed462e7bb37075d92 Mon Sep 17 00:00:00 2001
From: Chris Coulson <chris.coulson@canonical.com>
Date: Tue, 3 May 2022 16:02:19 +0200
Subject: [PATCH] pe: Perform image verification earlier when loading grub
The second stage loader was being verified after loading it into
memory. As an additional hardening measure to avoid performing risky
memcpys using header fields from a potentially specially crafted image,
perform the verification before this so that it can be rejected earlier.
Signed-off-by: Chris Coulson <chris.coulson@canonical.com>
---
pe.c | 42 +++++++++++++++++++++++++-----------------
1 file changed, 25 insertions(+), 17 deletions(-)
diff --git a/pe.c b/pe.c
index 1eb3f59..1d120f2 100644
--- a/pe.c
+++ b/pe.c
@@ -1106,7 +1106,31 @@ handle_image (void *data, unsigned int datasize,
}
/*
- * We only need to verify the binary if we're in secure mode
+ * Perform the image verification before we start copying data around
+ * in order to load it.
+ */
+ if (secure_mode ()) {
+ efi_status = verify_buffer(data, datasize, &context, sha256hash,
+ sha1hash);
+
+ if (EFI_ERROR(efi_status)) {
+ if (verbose)
+ console_print(L"Verification failed: %r\n", efi_status);
+ else
+ console_error(L"Verification failed", efi_status);
+ return efi_status;
+ } else {
+ if (verbose)
+ console_print(L"Verification succeeded\n");
+ }
+ }
+
+ /*
+ * Calculate the hash for the TPM measurement.
+ * XXX: We're computing these twice in secure boot mode when the
+ * buffers already contain the previously computed hashes. Also,
+ * this is only useful for the TPM1.2 case. We should try to fix
+ * this in a follow-up.
*/
efi_status = generate_hash(data, datasize, &context, sha256hash,
sha1hash);
@@ -1287,22 +1311,6 @@ handle_image (void *data, unsigned int datasize,
}
}
- if (secure_mode ()) {
- efi_status = verify_buffer(data, datasize, &context, sha256hash,
- sha1hash);
-
- if (EFI_ERROR(efi_status)) {
- if (verbose)
- console_print(L"Verification failed: %r\n", efi_status);
- else
- console_error(L"Verification failed", efi_status);
- return efi_status;
- } else {
- if (verbose)
- console_print(L"Verification succeeded\n");
- }
- }
-
if (context.NumberOfRvaAndSizes <= EFI_IMAGE_DIRECTORY_ENTRY_BASERELOC) {
perror(L"Image has no relocation entry\n");
FreePool(buffer);
--
2.27.0

View File

@ -1,28 +0,0 @@
From 349a41da1ad88ad87825414752a8ff5fdd6a6c3f Mon Sep 17 00:00:00 2001
From: Billy Brumley <bbrumley@gmail.com>
Date: Wed, 11 Apr 2018 10:10:58 +0300
Subject: [PATCH] RSA key generation: ensure BN_mod_inverse and BN_mod_exp_mont
both get called with BN_FLG_CONSTTIME flag set.
CVE-2018-0737
Reviewed-by: Rich Salz <rsalz@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(cherry picked from commit 6939eab03a6e23d2bd2c3f5e34fe1d48e542e787)
---
crypto/rsa/rsa_gen.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/Cryptlib/OpenSSL/crypto/rsa/rsa_gen.c b/Cryptlib/OpenSSL/crypto/rsa/rsa_gen.c
index 9ca5dfefb70..42b89a8dfaa 100644
--- a/Cryptlib/OpenSSL/crypto/rsa/rsa_gen.c
+++ b/Cryptlib/OpenSSL/crypto/rsa/rsa_gen.c
@@ -156,6 +156,8 @@ static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value,
if (BN_copy(rsa->e, e_value) == NULL)
goto err;
+ BN_set_flags(rsa->p, BN_FLG_CONSTTIME);
+ BN_set_flags(rsa->q, BN_FLG_CONSTTIME);
BN_set_flags(r2, BN_FLG_CONSTTIME);
/* generate p and q */
for (;;) {

View File

@ -1,79 +0,0 @@
Backport of:
From 6a51b9e1d0cf0bf8515f7201b68fb0a3482b3dc1 Mon Sep 17 00:00:00 2001
From: Matt Caswell <matt@openssl.org>
Date: Tue, 2 Feb 2021 17:17:23 +0000
Subject: [PATCH] Don't overflow the output length in EVP_CipherUpdate calls
CVE-2021-23840
Reviewed-by: Paul Dale <pauli@openssl.org>
---
crypto/err/openssl.txt | 3 ++-
crypto/evp/evp_enc.c | 27 +++++++++++++++++++++++++++
crypto/evp/evp_err.c | 4 +++-
include/openssl/evperr.h | 7 +++----
4 files changed, 35 insertions(+), 6 deletions(-)
--- a/Cryptlib/OpenSSL/crypto/evp/evp_enc.c
+++ b/Cryptlib/OpenSSL/crypto/evp/evp_enc.c
@@ -354,6 +354,19 @@ int EVP_EncryptUpdate(EVP_CIPHER_CTX *ct
return 1;
} else {
j = bl - i;
+
+ /*
+ * Once we've processed the first j bytes from in, the amount of
+ * data left that is a multiple of the block length is:
+ * (inl - j) & ~(bl - 1)
+ * We must ensure that this amount of data, plus the one block that
+ * we process from ctx->buf does not exceed INT_MAX
+ */
+ if (((inl - j) & ~(bl - 1)) > INT_MAX - bl) {
+ EVPerr(EVP_F_EVP_ENCRYPTDECRYPTUPDATE,
+ EVP_R_OUTPUT_WOULD_OVERFLOW);
+ return 0;
+ }
memcpy(&(ctx->buf[i]), in, j);
if (!M_do_cipher(ctx, out, ctx->buf, bl))
return 0;
@@ -455,6 +468,19 @@ int EVP_DecryptUpdate(EVP_CIPHER_CTX *ct
OPENSSL_assert(b <= sizeof ctx->final);
if (ctx->final_used) {
+ /*
+ * final_used is only ever set if buf_len is 0. Therefore the maximum
+ * length output we will ever see from evp_EncryptDecryptUpdate is
+ * the maximum multiple of the block length that is <= inl, or just:
+ * inl & ~(b - 1)
+ * Since final_used has been set then the final output length is:
+ * (inl & ~(b - 1)) + b
+ * This must never exceed INT_MAX
+ */
+ if ((inl & ~(b - 1)) > INT_MAX - b) {
+ EVPerr(EVP_F_EVP_DECRYPTUPDATE, EVP_R_OUTPUT_WOULD_OVERFLOW);
+ return 0;
+ }
memcpy(out, ctx->final, b);
out += b;
fix_len = 1;
--- a/Cryptlib/OpenSSL/crypto/evp/evp_err.c
+++ b/Cryptlib/OpenSSL/crypto/evp/evp_err.c
@@ -215,6 +215,7 @@ static ERR_STRING_DATA EVP_str_reasons[]
{ERR_REASON(EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE),
"operation not supported for this keytype"},
{ERR_REASON(EVP_R_OPERATON_NOT_INITIALIZED), "operaton not initialized"},
+ {ERR_REASON(EVP_R_OUTPUT_WOULD_OVERFLOW), "output would overflow"},
{ERR_REASON(EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE),
"pkcs8 unknown broken type"},
{ERR_REASON(EVP_R_PRIVATE_KEY_DECODE_ERROR), "private key decode error"},
--- a/Cryptlib/Include/openssl/evp.h
+++ b/Cryptlib/Include/openssl/evp.h
@@ -1509,6 +1509,7 @@ void ERR_load_EVP_strings(void);
# define EVP_R_NO_VERIFY_FUNCTION_CONFIGURED 105
# define EVP_R_OPERATION_NOT_SUPPORTED_FOR_THIS_KEYTYPE 150
# define EVP_R_OPERATON_NOT_INITIALIZED 151
+# define EVP_R_OUTPUT_WOULD_OVERFLOW 184
# define EVP_R_PKCS8_UNKNOWN_BROKEN_TYPE 117
# define EVP_R_PRIVATE_KEY_DECODE_ERROR 145
# define EVP_R_PRIVATE_KEY_ENCODE_ERROR 146

View File

@ -1,58 +0,0 @@
From 32492093722636596018a799c438bfc04c343b40 Mon Sep 17 00:00:00 2001
From: Rich Salz <rsalz@openssl.org>
Date: Mon, 6 Mar 2017 09:54:17 -0500
Subject: [PATCH] Fix an endless loop in rsa_builtin_keygen.
Cherry-picked by Matt Caswell from 69795831.
Reviewed-by: Richard Levitte <levitte@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/4670)
---
crypto/rsa/rsa_gen.c | 23 +++++++++++------------
1 file changed, 11 insertions(+), 12 deletions(-)
diff --git a/Cryptlib/OpenSSL/crypto/rsa/rsa_gen.c b/Cryptlib/OpenSSL/crypto/rsa/rsa_gen.c
index 082c8da2efc..a85493d6097 100644
--- a/Cryptlib/OpenSSL/crypto/rsa/rsa_gen.c
+++ b/Cryptlib/OpenSSL/crypto/rsa/rsa_gen.c
@@ -110,6 +110,16 @@ static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value,
int bitsp, bitsq, ok = -1, n = 0;
BN_CTX *ctx = NULL;
+ /*
+ * When generating ridiculously small keys, we can get stuck
+ * continually regenerating the same prime values.
+ */
+ if (bits < 16) {
+ ok = 0; /* we set our own err */
+ RSAerr(RSA_F_RSA_BUILTIN_KEYGEN, RSA_R_KEY_SIZE_TOO_SMALL);
+ goto err;
+ }
+
ctx = BN_CTX_new();
if (ctx == NULL)
goto err;
@@ -161,21 +171,10 @@ static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value,
if (!BN_GENCB_call(cb, 3, 0))
goto err;
for (;;) {
- /*
- * When generating ridiculously small keys, we can get stuck
- * continually regenerating the same prime values. Check for this and
- * bail if it happens 3 times.
- */
- unsigned int degenerate = 0;
do {
if (!BN_generate_prime_ex(rsa->q, bitsq, 0, NULL, NULL, cb))
goto err;
- } while ((BN_cmp(rsa->p, rsa->q) == 0) && (++degenerate < 3));
- if (degenerate == 3) {
- ok = 0; /* we set our own err */
- RSAerr(RSA_F_RSA_BUILTIN_KEYGEN, RSA_R_KEY_SIZE_TOO_SMALL);
- goto err;
- }
+ } while (BN_cmp(rsa->p, rsa->q) == 0);
if (!BN_sub(r2, rsa->q, BN_value_one()))
goto err;
if (!BN_gcd(r1, r2, rsa->e, ctx))

View File

@ -1,79 +0,0 @@
From 0b199a883e9170cdfe8e61c150bbaf8d8951f3e7 Mon Sep 17 00:00:00 2001
From: Samuel Weiser <samuel.weiser@iaik.tugraz.at>
Date: Tue, 5 Dec 2017 15:55:17 +0100
Subject: [PATCH] Replaced variable-time GCD with consttime inversion to avoid
side-channel attacks on RSA key generation
Reviewed-by: Rich Salz <rsalz@openssl.org>
Reviewed-by: Kurt Roeckx <kurt@roeckx.be>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/5170)
(cherry picked from commit 9db724cfede4ba7a3668bff533973ee70145ec07)
---
crypto/rsa/rsa_gen.c | 30 ++++++++++++++++++++++++------
1 file changed, 24 insertions(+), 6 deletions(-)
diff --git a/Cryptlib/OpenSSL/crypto/rsa/rsa_gen.c b/Cryptlib/OpenSSL/crypto/rsa/rsa_gen.c
index a85493d6097..8553772f062 100644
--- a/Cryptlib/OpenSSL/crypto/rsa/rsa_gen.c
+++ b/Cryptlib/OpenSSL/crypto/rsa/rsa_gen.c
@@ -109,6 +109,7 @@ static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value,
BIGNUM *pr0, *d, *p;
int bitsp, bitsq, ok = -1, n = 0;
BN_CTX *ctx = NULL;
+ unsigned long error = 0;
/*
* When generating ridiculously small keys, we can get stuck
@@ -155,16 +156,25 @@ static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value,
if (BN_copy(rsa->e, e_value) == NULL)
goto err;
+ BN_set_flags(rsa->e, BN_FLG_CONSTTIME);
/* generate p and q */
for (;;) {
if (!BN_generate_prime_ex(rsa->p, bitsp, 0, NULL, NULL, cb))
goto err;
if (!BN_sub(r2, rsa->p, BN_value_one()))
goto err;
- if (!BN_gcd(r1, r2, rsa->e, ctx))
- goto err;
- if (BN_is_one(r1))
+ if (BN_mod_inverse(r1, r2, rsa->e, ctx) != NULL) {
+ /* GCD == 1 since inverse exists */
break;
+ }
+ error = ERR_peek_last_error();
+ if (ERR_GET_LIB(error) == ERR_LIB_BN
+ && ERR_GET_REASON(error) == BN_R_NO_INVERSE) {
+ /* GCD != 1 */
+ ERR_clear_error();
+ } else {
+ goto err;
+ }
if (!BN_GENCB_call(cb, 2, n++))
goto err;
}
@@ -177,10 +187,18 @@ static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value,
} while (BN_cmp(rsa->p, rsa->q) == 0);
if (!BN_sub(r2, rsa->q, BN_value_one()))
goto err;
- if (!BN_gcd(r1, r2, rsa->e, ctx))
- goto err;
- if (BN_is_one(r1))
+ if (BN_mod_inverse(r1, r2, rsa->e, ctx) != NULL) {
+ /* GCD == 1 since inverse exists */
break;
+ }
+ error = ERR_peek_last_error();
+ if (ERR_GET_LIB(error) == ERR_LIB_BN
+ && ERR_GET_REASON(error) == BN_R_NO_INVERSE) {
+ /* GCD != 1 */
+ ERR_clear_error();
+ } else {
+ goto err;
+ }
if (!BN_GENCB_call(cb, 2, n++))
goto err;
}

View File

@ -1,135 +0,0 @@
From 34e3ef205c5d65139eacba8891fa773c03174679 Mon Sep 17 00:00:00 2001
From: Gary Lin <glin@suse.com>
Date: Wed, 16 Jun 2021 16:13:32 +0800
Subject: [PATCH] arm/aa64: fix the size of .rela* sections
The previous commit(*) merged .rel* and .dyn* into .rodata, and this
made ld to generate the wrong size for .rela* sections that covered
other unrelated sections. When the EFI image was loaded, _relocate()
went through the unexpected data and may cause unexpected crash.
This commit moves .rel* and .dyn* out of .rodata in the ld script but
also moves the related variables, such as _evrodata, _rodata_size,
and _rodata_vsize, to the end of the new .dyn section, so that the
crafted pe-coff section header for .rodata still covers our new
.rela and .dyn sections.
(*) 212ba30544f ("arm/aa64 targets: put .rel* and .dyn* in .rodata")
Fix issue: https://github.com/rhboot/shim/issues/371
Signed-off-by: Gary Lin <glin@suse.com>
---
Makefile | 4 ++--
elf_aarch64_efi.lds | 24 ++++++++++++++++--------
elf_arm_efi.lds | 24 ++++++++++++++++--------
3 files changed, 34 insertions(+), 18 deletions(-)
diff --git a/Makefile b/Makefile
index 050c921..45db2b5 100644
--- a/Makefile
+++ b/Makefile
@@ -247,7 +247,7 @@ ifneq ($(OBJCOPY_GTE224),1)
endif
$(OBJCOPY) -D -j .text -j .sdata -j .data -j .data.ident \
-j .dynamic -j .rodata -j .rel* \
- -j .rela* -j .reloc -j .eh_frame \
+ -j .rela* -j .dyn -j .reloc -j .eh_frame \
-j .vendor_cert -j .sbat \
$(FORMAT) $< $@
# I am tired of wasting my time fighting binutils timestamp code.
@@ -263,7 +263,7 @@ ifneq ($(OBJCOPY_GTE224),1)
endif
$(OBJCOPY) -D -j .text -j .sdata -j .data \
-j .dynamic -j .rodata -j .rel* \
- -j .rela* -j .reloc -j .eh_frame -j .sbat \
+ -j .rela* -j .dyn -j .reloc -j .eh_frame -j .sbat \
-j .debug_info -j .debug_abbrev -j .debug_aranges \
-j .debug_line -j .debug_str -j .debug_ranges \
-j .note.gnu.build-id \
diff --git a/elf_aarch64_efi.lds b/elf_aarch64_efi.lds
index 353b24a..42825fd 100644
--- a/elf_aarch64_efi.lds
+++ b/elf_aarch64_efi.lds
@@ -70,21 +70,29 @@ SECTIONS
.rodata :
{
_rodata = .;
- *(.rela.dyn)
- *(.rela.plt)
- *(.rela.got)
- *(.rela.data)
- *(.rela.data*)
-
*(.rodata*)
*(.srodata)
- *(.dynsym)
- *(.dynstr)
. = ALIGN(16);
*(.note.gnu.build-id)
. = ALIGN(4096);
*(.vendor_cert)
*(.data.ident)
+ . = ALIGN(4096);
+ }
+ . = ALIGN(4096);
+ .rela :
+ {
+ *(.rela.dyn)
+ *(.rela.plt)
+ *(.rela.got)
+ *(.rela.data)
+ *(.rela.data*)
+ }
+ . = ALIGN(4096);
+ .dyn :
+ {
+ *(.dynsym)
+ *(.dynstr)
_evrodata = .;
. = ALIGN(4096);
}
diff --git a/elf_arm_efi.lds b/elf_arm_efi.lds
index e4e29bd..5334621 100644
--- a/elf_arm_efi.lds
+++ b/elf_arm_efi.lds
@@ -70,21 +70,29 @@ SECTIONS
.rodata :
{
_rodata = .;
- *(.rel.dyn)
- *(.rel.plt)
- *(.rel.got)
- *(.rel.data)
- *(.rel.data*)
-
*(.rodata*)
*(.srodata)
- *(.dynsym)
- *(.dynstr)
. = ALIGN(16);
*(.note.gnu.build-id)
. = ALIGN(4096);
*(.vendor_cert)
*(.data.ident)
+ . = ALIGN(4096);
+ }
+ . = ALIGN(4096);
+ .rela :
+ {
+ *(.rela.dyn)
+ *(.rela.plt)
+ *(.rela.got)
+ *(.rela.data)
+ *(.rela.data*)
+ }
+ . = ALIGN(4096);
+ .dyn :
+ {
+ *(.dynsym)
+ *(.dynstr)
_evrodata = .;
. = ALIGN(4096);
}
--
2.27.0

View File

@ -1,28 +0,0 @@
From 0d6710289307d277ebc3354105c965b6e8ba8eb0 Mon Sep 17 00:00:00 2001
From: Samuel Weiser <samuel.weiser@iaik.tugraz.at>
Date: Fri, 9 Feb 2018 14:11:47 +0100
Subject: [PATCH] consttime flag changed
Reviewed-by: Rich Salz <rsalz@openssl.org>
Reviewed-by: Kurt Roeckx <kurt@roeckx.be>
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/5170)
(cherry picked from commit 7150a4720af7913cae16f2e4eaf768b578c0b298)
---
crypto/rsa/rsa_gen.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Cryptlib/OpenSSL/crypto/rsa/rsa_gen.c b/Cryptlib/OpenSSL/crypto/rsa/rsa_gen.c
index 610d82db665..9ca5dfefb70 100644
--- a/Cryptlib/OpenSSL/crypto/rsa/rsa_gen.c
+++ b/Cryptlib/OpenSSL/crypto/rsa/rsa_gen.c
@@ -156,7 +156,7 @@ static int rsa_builtin_keygen(RSA *rsa, int bits, BIGNUM *e_value,
if (BN_copy(rsa->e, e_value) == NULL)
goto err;
- BN_set_flags(rsa->e, BN_FLG_CONSTTIME);
+ BN_set_flags(r2, BN_FLG_CONSTTIME);
/* generate p and q */
for (;;) {
if (!BN_generate_prime_ex(rsa->p, bitsp, 0, NULL, NULL, cb))

View File

@ -1,38 +0,0 @@
Backport of:
From 4bd0db1feaaf97fbc2bd31f54f1fbdeab80b2b1a Mon Sep 17 00:00:00 2001
From: Richard Levitte <levitte@openssl.org>
Date: Sun, 9 Dec 2018 14:20:30 +0100
Subject: [PATCH] make update
Reviewed-by: Kurt Roeckx <kurt@roeckx.be>
Reviewed-by: Paul Dale <paul.dale@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/7852)
(cherry picked from commit f2f734d4f9e34643a1d3e5b79d2447cd643519f8)
---
crypto/err/openssl.txt | 1 +
crypto/evp/evp_err.c | 2 ++
include/openssl/evperr.h | 1 +
3 files changed, 4 insertions(+)
--- a/Cryptlib/OpenSSL/crypto/evp/evp_err.c
+++ b/Cryptlib/OpenSSL/crypto/evp/evp_err.c
@@ -94,6 +94,7 @@ static ERR_STRING_DATA EVP_str_functs[]
{ERR_FUNC(EVP_F_EVP_DECRYPTFINAL_EX), "EVP_DecryptFinal_ex"},
{ERR_FUNC(EVP_F_EVP_DECRYPTUPDATE), "EVP_DecryptUpdate"},
{ERR_FUNC(EVP_F_EVP_DIGESTINIT_EX), "EVP_DigestInit_ex"},
+ {ERR_FUNC(EVP_F_EVP_ENCRYPTDECRYPTUPDATE), "evp_EncryptDecryptUpdate"},
{ERR_FUNC(EVP_F_EVP_ENCRYPTFINAL_EX), "EVP_EncryptFinal_ex"},
{ERR_FUNC(EVP_F_EVP_ENCRYPTUPDATE), "EVP_EncryptUpdate"},
{ERR_FUNC(EVP_F_EVP_MD_CTX_COPY_EX), "EVP_MD_CTX_copy_ex"},
--- a/Cryptlib/Include/openssl/evp.h
+++ b/Cryptlib/Include/openssl/evp.h
@@ -1398,6 +1398,7 @@ void ERR_load_EVP_strings(void);
# define EVP_F_EVP_DECRYPTFINAL_EX 101
# define EVP_F_EVP_DECRYPTUPDATE 166
# define EVP_F_EVP_DIGESTINIT_EX 128
+# define EVP_F_EVP_ENCRYPTDECRYPTUPDATE 219
# define EVP_F_EVP_ENCRYPTFINAL_EX 127
# define EVP_F_EVP_ENCRYPTUPDATE 167
# define EVP_F_EVP_MD_CTX_COPY_EX 110

View File

@ -1,41 +0,0 @@
Partial backport of:
From 83151b73a4736bca1797f8edc2b0ad4cf7ac9146 Mon Sep 17 00:00:00 2001
From: Andy Polyakov <appro@openssl.org>
Date: Mon, 25 Jul 2016 15:02:26 +0200
Subject: [PATCH] evp/evp_enc.c: make assert error message more readable and
add EVPerr(PARTIALLY_OVERLAPPED)
Reviewed-by: Stephen Henson <steve@openssl.org>
---
crypto/evp/evp_enc.c | 28 +++++++++++++++++++---------
crypto/evp/evp_err.c | 3 +++
include/openssl/evp.h | 3 +++
3 files changed, 25 insertions(+), 9 deletions(-)
--- a/Cryptlib/OpenSSL/crypto/evp/evp_err.c
+++ b/Cryptlib/OpenSSL/crypto/evp/evp_err.c
@@ -92,8 +92,10 @@ static ERR_STRING_DATA EVP_str_functs[]
{ERR_FUNC(EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH),
"EVP_CIPHER_CTX_set_key_length"},
{ERR_FUNC(EVP_F_EVP_DECRYPTFINAL_EX), "EVP_DecryptFinal_ex"},
+ {ERR_FUNC(EVP_F_EVP_DECRYPTUPDATE), "EVP_DecryptUpdate"},
{ERR_FUNC(EVP_F_EVP_DIGESTINIT_EX), "EVP_DigestInit_ex"},
{ERR_FUNC(EVP_F_EVP_ENCRYPTFINAL_EX), "EVP_EncryptFinal_ex"},
+ {ERR_FUNC(EVP_F_EVP_ENCRYPTUPDATE), "EVP_EncryptUpdate"},
{ERR_FUNC(EVP_F_EVP_MD_CTX_COPY_EX), "EVP_MD_CTX_copy_ex"},
{ERR_FUNC(EVP_F_EVP_MD_SIZE), "EVP_MD_size"},
{ERR_FUNC(EVP_F_EVP_OPENINIT), "EVP_OpenInit"},
--- a/Cryptlib/Include/openssl/evp.h
+++ b/Cryptlib/Include/openssl/evp.h
@@ -1396,8 +1396,10 @@ void ERR_load_EVP_strings(void);
# define EVP_F_EVP_CIPHER_CTX_CTRL 124
# define EVP_F_EVP_CIPHER_CTX_SET_KEY_LENGTH 122
# define EVP_F_EVP_DECRYPTFINAL_EX 101
+# define EVP_F_EVP_DECRYPTUPDATE 166
# define EVP_F_EVP_DIGESTINIT_EX 128
# define EVP_F_EVP_ENCRYPTFINAL_EX 127
+# define EVP_F_EVP_ENCRYPTUPDATE 167
# define EVP_F_EVP_MD_CTX_COPY_EX 110
# define EVP_F_EVP_MD_SIZE 162
# define EVP_F_EVP_OPENINIT 102

View File

@ -1,41 +0,0 @@
From b1fead0f7c9a09634057317a7bd2a5c94258e5df Mon Sep 17 00:00:00 2001
From: Gary Lin <glin@suse.com>
Date: Wed, 30 Jun 2021 16:34:51 +0800
Subject: [PATCH] mok: delete the existing RT variables only when
only_first=TRUE
For the firmware without the variable writing issues, MOK variables are
mirrored when only_first=TRUE. However, LibDeleteVariable() was called
in maybe_mirror_one_mok_variable() when only_first=FALSE, and this
could delete MOK variables that were just mirrored in the first round.
This bug was hidden since LibDeleteVariable() deletes BS+RT+NV variables
while we mirror MOK variables as BS+RT, and the firmware refused to
delete the mirrored MOK variable due to mismatching attributes. However,
some firmwares, such as VMWare, didn't enforce the attribute check and
just deleted the variables with matched name and GUID. In such system,
MokListRT was always removed before it reached OS.
Fixes: https://github.com/rhboot/shim/issues/386
Signed-off-by: Gary Lin <glin@suse.com>
---
mok.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/mok.c b/mok.c
index 454672b..84e51f3 100644
--- a/mok.c
+++ b/mok.c
@@ -868,7 +868,7 @@ maybe_mirror_one_mok_variable(struct mok_state_variable *v,
BOOLEAN present = FALSE;
if (v->rtname) {
- if (!only_first && (v->flags & MOK_MIRROR_DELETE_FIRST)) {
+ if (only_first && (v->flags & MOK_MIRROR_DELETE_FIRST)) {
dprint(L"deleting \"%s\"\n", v->rtname);
efi_status = LibDeleteVariable(v->rtname, v->guid);
dprint(L"LibDeleteVariable(\"%s\",...) => %r\n", v->rtname, efi_status);
--
2.27.0

View File

@ -1,43 +0,0 @@
From 3f327f546c219634b24cfd9abe9ec987bbb6ad14 Mon Sep 17 00:00:00 2001
From: Gary Lin <glin@suse.com>
Date: Wed, 5 May 2021 11:25:07 +0800
Subject: [PATCH] mok: relax the maximum variable size check
Some UEFI environment such as u-boot doesn't implement
QueryVariableInfo(), so we couldn't rely on the function to estimate the
available space for RT variables. All we can do is to call SetVariable()
directly and check the return value of SetVariable().
Signed-off-by: Gary Lin <glin@suse.com>
---
mok.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/mok.c b/mok.c
index db18093..454672b 100644
--- a/mok.c
+++ b/mok.c
@@ -364,13 +364,18 @@ mirror_mok_db(CHAR16 *name, CHAR8 *name8, EFI_GUID *guid, UINT32 attrs,
SIZE_T max_var_sz;
efi_status = get_max_var_sz(attrs, &max_var_sz);
- if (EFI_ERROR(efi_status)) {
+ if (EFI_ERROR(efi_status) && efi_status != EFI_UNSUPPORTED) {
LogError(L"Could not get maximum variable size: %r",
efi_status);
return efi_status;
}
- if (FullDataSize <= max_var_sz) {
+ /* Some UEFI environment such as u-boot doesn't implement
+ * QueryVariableInfo() and we will only get EFI_UNSUPPORTED when
+ * querying the available space. In this case, we just mirror
+ * the variable directly. */
+ if (FullDataSize <= max_var_sz || efi_status == EFI_UNSUPPORTED) {
+ efi_status = EFI_SUCCESS;
if (only_first)
efi_status = SetVariable(name, guid, attrs,
FullDataSize, FullData);
--
2.27.0

View File

@ -1,402 +0,0 @@
From 4d64389c6c941d21548b06423b8131c872e3c3c7 Mon Sep 17 00:00:00 2001
From: Chris Coulson <chris.coulson@canonical.com>
Date: Mon, 7 Jun 2021 16:34:18 +0100
Subject: [PATCH] shim: another attempt to fix load options handling
The load options handling is quite complicated and tries to accomodate
several scenarios, but there are currently multiple issues:
- If the supplied LoadOptions is an EFI_LOAD_OPTION structure,
second_stage gets initialized to the entire contents of the OptionalData
field and load_options is initialized to NULL, which means it isn't
possible to pass additional options to the second stage loader (and it
looks like the intention is for this to be supported).
- If the supplied LoadOptions contains 2 or more strings, the code seems
to assume that shim was executed from the UEFI shell and that the first
argument is the path of the shim executable, so it's ignored. But this
breaks the ability to pass additional options to the second stage loader
from BDS on firmware implementations that initialize LoadOptions to just
the OptionalData field of the EFI_LOAD_OPTION, which is what EDK2 seems
to do.
This is moot anyway because this case (strings == 2) doesn't actually seem
to work, as nothing sets loader_len and therefore second_stage is not set
to the custom loader path.
- If the supplied LoadOptions contains a single string that isn't shim's
path, nothing sets loader_len and therefore second_stage isn't set at the
end of set_second_stage.
- set_second_stage replaces L' ' characters with L'\0' - whilst this is
useful to NULL terminate the path for the second stage, it doesn't seem
quite right to do this for the remaining LoadOptions data. Grub's
chainloader command supplies additional arguments as a NULL-terminated
space-delimited string via LoadOptions. Making it NULL-delimited seems to
be incompatible with the kernel's commandline handling, which wouldn't
work for scenarios where you might want to direct-boot a kernel image
(wrapped in systemd's EFI stub) from shim.
- handle_image passes the original LoadOptions to the second stage if
load_options is NULL, which means that the second stage currently always
gets shim's load options.
I've made an attempt to try to fix things. After the initial
checks in set_second_stage, it now does this:
- Tries to parse LoadOptions as an EFI_LOAD_OPTION in order to extract
the OptionalData if it is.
- If it's not an EFI_LOAD_OPTION, check if the first string is the
current shim path and ignore it if it is (the UEFI shell case).
- Split LoadOptions in to a single NULL terminated string (used to
initialize second_stage) and the unmodified remaining data (used to
initialize load_options and load_options_size).
I've also modified handle_image to always set LoadOptions and
LoadOptionsSize. If shim is executed with no options, or is only
executed with a single option to override the second stage loader
path, the second stage is executed with LoadOptions = NULL and
LoadOptionsSize = 0 now.
I've tested this on EDK2 and I can load a custom loader with extra
options from both BDS and the UEFI shell:
FS0:\> shimx64.efi test.efi
LoadOptionsSize: 0
LoadOptions: (null)
FS0:\> shimx64.efi test.efi
LoadOptionsSize: 0
LoadOptions: (null)
FS0:\> shimx64.efi test.efi foo bar
LoadOptionsSize: 16
LoadOptions: foo bar
---
include/ucs2.h | 27 -------
pe.c | 6 +-
shim.c | 200 ++++++++++++++++++++++---------------------------
3 files changed, 92 insertions(+), 141 deletions(-)
diff --git a/include/ucs2.h b/include/ucs2.h
index e43c341..ee038ce 100644
--- a/include/ucs2.h
+++ b/include/ucs2.h
@@ -81,31 +81,4 @@ is_all_nuls(UINT8 *data, UINTN data_size)
return true;
}
-static inline UINTN
-__attribute__((__unused__))
-count_ucs2_strings(UINT8 *data, UINTN data_size)
-{
- UINTN pos = 0;
- UINTN last_nul_pos = 0;
- UINTN num_nuls = 0;
- UINTN i;
-
- if (data_size % 2 != 0)
- return 0;
-
- for (i = pos; i < data_size; i++) {
- if (i % 2 != 0) {
- if (data[i] != 0)
- return 0;
- } else if (data[i] == 0) {
- last_nul_pos = i;
- num_nuls++;
- }
- pos = i;
- }
- if (num_nuls > 0 && last_nul_pos != pos - 1)
- return 0;
- return num_nuls;
-}
-
#endif /* SHIM_UCS2_H */
diff --git a/pe.c b/pe.c
index 365e32a..13bc397 100644
--- a/pe.c
+++ b/pe.c
@@ -1144,10 +1144,8 @@ handle_image (void *data, unsigned int datasize,
li->ImageSize = context.ImageSize;
/* Pass the load options to the second stage loader */
- if ( load_options ) {
- li->LoadOptions = load_options;
- li->LoadOptionsSize = load_options_size;
- }
+ li->LoadOptions = load_options;
+ li->LoadOptionsSize = load_options_size;
if (!found_entry_point) {
perror(L"Entry point is not within sections\n");
diff --git a/shim.c b/shim.c
index 40e4894..ecf6ee5 100644
--- a/shim.c
+++ b/shim.c
@@ -1241,9 +1241,13 @@ EFI_STATUS init_grub(EFI_HANDLE image_handle)
return efi_status;
}
+/*
+ * Extract the OptionalData and OptionalData fields from an
+ * EFI_LOAD_OPTION.
+ */
static inline EFI_STATUS
-get_load_option_optional_data(UINT8 *data, UINTN data_size,
- UINT8 **od, UINTN *ods)
+get_load_option_optional_data(VOID *data, UINT32 data_size,
+ VOID **od, UINT32 *ods)
{
/*
* If it's not at least Attributes + FilePathListLength +
@@ -1253,7 +1257,8 @@ get_load_option_optional_data(UINT8 *data, UINTN data_size,
if (data_size < (sizeof(UINT32) + sizeof(UINT16) + 2 + 4))
return EFI_INVALID_PARAMETER;
- UINT8 *cur = data + sizeof(UINT32);
+ UINT8 *start = (UINT8 *)data;
+ UINT8 *cur = start + sizeof(UINT32);
UINT16 fplistlen = *(UINT16 *)cur;
/*
* If there's not enough space for the file path list and the
@@ -1263,8 +1268,8 @@ get_load_option_optional_data(UINT8 *data, UINTN data_size,
return EFI_INVALID_PARAMETER;
cur += sizeof(UINT16);
- UINTN limit = data_size - (cur - data) - fplistlen;
- UINTN i;
+ UINT32 limit = data_size - (cur - start) - fplistlen;
+ UINT32 i;
for (i = 0; i < limit ; i++) {
/* If the description isn't valid UCS2-LE, it's not valid. */
if (i % 2 != 0) {
@@ -1380,6 +1385,57 @@ done:
return ret;
}
+/*
+ * Split the supplied load options in to a NULL terminated
+ * string representing the path of the second stage loader,
+ * and return a pointer to the remaining load options data
+ * and its remaining size.
+ *
+ * This expects the supplied load options to begin with a
+ * string that is either NULL terminated or terminated with
+ * a space and some optional data. It will return NULL if
+ * the supplied load options contains no spaces or NULL
+ * terminators.
+ */
+static CHAR16 *
+split_load_options(VOID *in, UINT32 in_size,
+ VOID **remaining,
+ UINT32 *remaining_size) {
+ UINTN i;
+ CHAR16 *arg0 = NULL;
+ CHAR16 *start = (CHAR16 *)in;
+
+ /* Skip spaces */
+ for (i = 0; i < in_size / sizeof(CHAR16); i++) {
+ if (*start != L' ')
+ break;
+
+ start++;
+ }
+
+ in_size -= ((VOID *)start - in);
+
+ /*
+ * Ensure that the first argument is NULL terminated by
+ * replacing L' ' with L'\0'.
+ */
+ for (i = 0; i < in_size / sizeof(CHAR16); i++) {
+ if (start[i] == L' ' || start[i] == L'\0') {
+ start[i] = L'\0';
+ arg0 = (CHAR16 *)start;
+ break;
+ }
+ }
+
+ if (arg0) {
+ UINTN skip = i + 1;
+ *remaining_size = in_size - (skip * sizeof(CHAR16));
+ *remaining = *remaining_size > 0 ? start + skip : NULL;
+ }
+
+ return arg0;
+}
+
/*
* Check the load options to specify the second stage loader
*/
@@ -1387,20 +1443,11 @@ EFI_STATUS set_second_stage (EFI_HANDLE image_handle)
{
EFI_STATUS efi_status;
EFI_LOADED_IMAGE *li = NULL;
- CHAR16 *start = NULL;
- UINTN remaining_size = 0;
+ VOID *remaining = NULL;
+ UINT32 remaining_size;
CHAR16 *loader_str = NULL;
- UINTN loader_len = 0;
- unsigned int i;
- UINTN second_stage_len;
- second_stage_len = (StrLen(DEFAULT_LOADER) + 1) * sizeof(CHAR16);
- second_stage = AllocatePool(second_stage_len);
- if (!second_stage) {
- perror(L"Could not allocate %lu bytes\n", second_stage_len);
- return EFI_OUT_OF_RESOURCES;
- }
- StrCpy(second_stage, DEFAULT_LOADER);
+ second_stage = DEFAULT_LOADER;
load_options = NULL;
load_options_size = 0;
@@ -1499,105 +1546,44 @@ EFI_STATUS set_second_stage (EFI_HANDLE image_handle)
return EFI_SUCCESS;
/*
- * Check and see if this is just a list of strings. If it's an
- * EFI_LOAD_OPTION, it'll be 0, since we know EndEntire device path
- * won't pass muster as UCS2-LE.
- *
- * If there are 3 strings, we're launched from the shell most likely,
- * But we actually only care about the second one.
+ * See if this is an EFI_LOAD_OPTION and extract the optional
+ * data if it is. This will return an error if it is not a valid
+ * EFI_LOAD_OPTION.
*/
- UINTN strings = count_ucs2_strings(li->LoadOptions,
- li->LoadOptionsSize);
-
- /*
- * In some cases we get strings == 1 because BDS is using L' ' as the
- * delimeter:
- * 0000:74 00 65 00 73 00 74 00 2E 00 65 00 66 00 69 00 t.e.s.t...e.f.i.
- * 0016:20 00 6F 00 6E 00 65 00 20 00 74 00 77 00 6F 00 ..o.n.e...t.w.o.
- * 0032:20 00 74 00 68 00 72 00 65 00 65 00 00 00 ..t.h.r.e.e...
- *
- * If so replace it with NULs since the code already handles that
- * case.
- */
- if (strings == 1) {
- UINT16 *cur = start = li->LoadOptions;
-
- /* replace L' ' with L'\0' if we find any */
- for (i = 0; i < li->LoadOptionsSize / 2; i++) {
- if (cur[i] == L' ')
- cur[i] = L'\0';
- }
-
- /* redo the string count */
- strings = count_ucs2_strings(li->LoadOptions,
- li->LoadOptionsSize);
- }
-
- /*
- * If it's not string data, try it as an EFI_LOAD_OPTION.
- */
- if (strings == 0) {
- /*
- * We at least didn't find /enough/ strings. See if it works
- * as an EFI_LOAD_OPTION.
- */
- efi_status = get_load_option_optional_data(li->LoadOptions,
- li->LoadOptionsSize,
- (UINT8 **)&start,
- &loader_len);
- if (EFI_ERROR(efi_status))
- return EFI_SUCCESS;
-
- remaining_size = 0;
- } else if (strings >= 2) {
+ efi_status = get_load_option_optional_data(li->LoadOptions,
+ li->LoadOptionsSize,
+ &li->LoadOptions,
+ &li->LoadOptionsSize);
+ if (EFI_ERROR(efi_status)) {
/*
+ * it's not an EFI_LOAD_OPTION, so it's probably just a string
+ * or list of strings.
+ *
* UEFI shell copies the whole line of the command into
- * LoadOptions. We ignore the string before the first L'\0',
- * i.e. the name of this program.
+ * LoadOptions. We ignore the first string, i.e. the name of this
+ * program in this case.
*/
- UINT16 *cur = li->LoadOptions;
- for (i = 1; i < li->LoadOptionsSize / 2; i++) {
- if (cur[i - 1] == L'\0') {
- start = &cur[i];
- remaining_size = li->LoadOptionsSize - (i * 2);
- break;
- }
+ CHAR16 *loader_str = split_load_options(li->LoadOptions,
+ li->LoadOptionsSize,
+ &remaining,
+ &remaining_size);
+
+ if (loader_str && is_our_path(li, loader_str)) {
+ li->LoadOptions = remaining;
+ li->LoadOptionsSize = remaining_size;
}
-
- remaining_size -= i * 2 + 2;
- } else if (strings == 1 && is_our_path(li, start)) {
- /*
- * And then I found a version of BDS that gives us our own path
- * in LoadOptions:
-
-77162C58 5c 00 45 00 46 00 49 00 |\.E.F.I.|
-77162C60 5c 00 42 00 4f 00 4f 00 54 00 5c 00 42 00 4f 00 |\.B.O.O.T.\.B.O.|
-77162C70 4f 00 54 00 58 00 36 00 34 00 2e 00 45 00 46 00 |O.T.X.6.4...E.F.|
-77162C80 49 00 00 00 |I...|
-
- * which is just cruel... So yeah, just don't use it.
- */
- return EFI_SUCCESS;
}
+ loader_str = split_load_options(li->LoadOptions, li->LoadOptionsSize,
+ &remaining, &remaining_size);
+
/*
* Set up the name of the alternative loader and the LoadOptions for
* the loader
*/
- if (loader_len > 0) {
- /* we might not always have a NULL at the end */
- loader_str = AllocatePool(loader_len + 2);
- if (!loader_str) {
- perror(L"Failed to allocate loader string\n");
- return EFI_OUT_OF_RESOURCES;
- }
-
- for (i = 0; i < loader_len / 2; i++)
- loader_str[i] = start[i];
- loader_str[loader_len/2] = L'\0';
-
+ if (loader_str) {
second_stage = loader_str;
- load_options = remaining_size ? start + (loader_len/2) : NULL;
+ load_options = remaining;
load_options_size = remaining_size;
}
@@ -1777,12 +1763,6 @@ shim_fini(void)
unhook_exit();
- /*
- * Free the space allocated for the alternative 2nd stage loader
- */
- if (load_options_size > 0 && second_stage)
- FreePool(second_stage);
-
console_fini();
}
--
2.27.0

View File

@ -1,225 +0,0 @@
From a2da05fcb8972628bec08e4adfc13abbafc319ad Mon Sep 17 00:00:00 2001
From: Chris Coulson <chris.coulson@canonical.com>
Date: Mon, 28 Feb 2022 21:29:16 +0000
Subject: [PATCH] shim: implement SBAT verification for the shim_lock protocol
This implements SBAT verification via the shim_lock protocol
by moving verification inside the existing verify_buffer()
function that is shared by both shim_verify() and handle_image().
The .sbat section is optional for code verified via the shim_lock
protocol, unlike for code that is verified and executed directly
by shim. For executables that don't have a .sbat section,
verification is skipped when using the protocol.
A vendor can enforce SBAT verification for code verified via the
shim_lock protocol by revoking all pre-SBAT binaries via a dbx
update or by using vendor_dbx and then only signing binaries that
have a .sbat section from that point.
Signed-off-by: Chris Coulson <chris.coulson@canonical.com>
---
include/pe.h | 2 +-
pe.c | 46 +++++++--------------------------
shim.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++---
3 files changed, 79 insertions(+), 42 deletions(-)
diff --git a/include/pe.h b/include/pe.h
index 43727f5..b86e1b3 100644
--- a/include/pe.h
+++ b/include/pe.h
@@ -15,7 +15,7 @@ read_header(void *data, unsigned int datasize,
PE_COFF_LOADER_IMAGE_CONTEXT *context);
EFI_STATUS
-handle_sbat(char *SBATBase, size_t SBATSize);
+verify_sbat_section(char *SBATBase, size_t SBATSize);
EFI_STATUS
handle_image (void *data, unsigned int datasize,
diff --git a/pe.c b/pe.c
index 92c2804..554e77c 100644
--- a/pe.c
+++ b/pe.c
@@ -820,7 +820,7 @@ read_header(void *data, unsigned int datasize,
}
EFI_STATUS
-handle_sbat(char *SBATBase, size_t SBATSize)
+verify_sbat_section(char *SBATBase, size_t SBATSize)
{
unsigned int i;
EFI_STATUS efi_status;
@@ -834,7 +834,12 @@ handle_sbat(char *SBATBase, size_t SBATSize)
if (SBATBase == NULL || SBATSize == 0) {
dprint(L"No .sbat section data\n");
- return EFI_SECURITY_VIOLATION;
+ /*
+ * SBAT is mandatory for binaries loaded by shim, but optional
+ * for binaries loaded outside of shim but verified via the
+ * protocol.
+ */
+ return in_protocol ? EFI_SUCCESS : EFI_SECURITY_VIOLATION;
}
sbat_size = SBATSize + 1;
@@ -980,9 +985,6 @@ handle_image (void *data, unsigned int datasize,
EFI_IMAGE_SECTION_HEADER *RelocSection = NULL;
- char *SBATBase = NULL;
- size_t SBATSize = 0;
-
/*
* Copy the executable's sections to their desired offsets
*/
@@ -1027,33 +1029,6 @@ handle_image (void *data, unsigned int datasize,
RelocBaseEnd == end) {
RelocSection = Section;
}
- } else if (CompareMem(Section->Name, ".sbat\0\0\0", 8) == 0) {
- if (SBATBase || SBATSize) {
- perror(L"Image has multiple SBAT sections\n");
- return EFI_UNSUPPORTED;
- }
-
- if (Section->NumberOfRelocations != 0 ||
- Section->PointerToRelocations != 0) {
- perror(L"SBAT section has relocations\n");
- return EFI_UNSUPPORTED;
- }
-
- /* The virtual size corresponds to the size of the SBAT
- * metadata and isn't necessarily a multiple of the file
- * alignment. The on-disk size is a multiple of the file
- * alignment and is zero padded. Make sure that the
- * on-disk size is at least as large as virtual size,
- * and ignore the section if it isn't. */
- if (Section->SizeOfRawData &&
- Section->SizeOfRawData >= Section->Misc.VirtualSize &&
- base && end) {
- SBATBase = base;
- /* +1 because of size vs last byte location */
- SBATSize = end - base + 1;
- dprint(L"sbat section base:0x%lx size:0x%lx\n",
- SBATBase, SBATSize);
- }
}
if (Section->Characteristics & EFI_IMAGE_SCN_MEM_DISCARDABLE) {
@@ -1095,11 +1070,8 @@ handle_image (void *data, unsigned int datasize,
}
if (secure_mode ()) {
- efi_status = handle_sbat(SBATBase, SBATSize);
-
- if (!EFI_ERROR(efi_status))
- efi_status = verify_buffer(data, datasize,
- &context, sha256hash, sha1hash);
+ efi_status = verify_buffer(data, datasize, &context, sha256hash,
+ sha1hash);
if (EFI_ERROR(efi_status)) {
if (verbose)
diff --git a/shim.c b/shim.c
index 604c0db..6d6b1e5 100644
--- a/shim.c
+++ b/shim.c
@@ -559,9 +559,9 @@ verify_one_signature(WIN_CERTIFICATE_EFI_PKCS *sig,
* Check that the signature is valid and matches the binary
*/
EFI_STATUS
-verify_buffer (char *data, int datasize,
- PE_COFF_LOADER_IMAGE_CONTEXT *context,
- UINT8 *sha256hash, UINT8 *sha1hash)
+verify_buffer_authenticode (char *data, int datasize,
+ PE_COFF_LOADER_IMAGE_CONTEXT *context,
+ UINT8 *sha256hash, UINT8 *sha1hash)
{
EFI_STATUS ret_efi_status;
size_t size = datasize;
@@ -695,6 +695,71 @@ verify_buffer (char *data, int datasize,
return ret_efi_status;
}
+/*
+ * Check that the binary is permitted to load by SBAT.
+ */
+EFI_STATUS
+verify_buffer_sbat (char *data, int datasize,
+ PE_COFF_LOADER_IMAGE_CONTEXT *context)
+{
+ int i;
+ EFI_IMAGE_SECTION_HEADER *Section;
+ char *SBATBase = NULL;
+ size_t SBATSize = 0;
+
+ Section = context->FirstSection;
+ for (i = 0; i < context->NumberOfSections; i++, Section++) {
+ if (CompareMem(Section->Name, ".sbat\0\0\0", 8) != 0)
+ continue;
+
+ if (SBATBase || SBATSize) {
+ perror(L"Image has multiple SBAT sections\n");
+ return EFI_UNSUPPORTED;
+ }
+
+ if (Section->NumberOfRelocations != 0 ||
+ Section->PointerToRelocations != 0) {
+ perror(L"SBAT section has relocations\n");
+ return EFI_UNSUPPORTED;
+ }
+
+ /* The virtual size corresponds to the size of the SBAT
+ * metadata and isn't necessarily a multiple of the file
+ * alignment. The on-disk size is a multiple of the file
+ * alignment and is zero padded. Make sure that the
+ * on-disk size is at least as large as virtual size,
+ * and ignore the section if it isn't. */
+ if (Section->SizeOfRawData &&
+ Section->SizeOfRawData >= Section->Misc.VirtualSize) {
+ SBATBase = ImageAddress(data, datasize,
+ Section->PointerToRawData);
+ SBATSize = Section->SizeOfRawData;
+ dprint(L"sbat section base:0x%lx size:0x%lx\n",
+ SBATBase, SBATSize);
+ }
+ }
+
+ return verify_sbat_section(SBATBase, SBATSize);
+}
+
+/*
+ * Check that the signature is valid and matches the binary and that
+ * the binary is permitted to load by SBAT.
+ */
+EFI_STATUS
+verify_buffer (char *data, int datasize,
+ PE_COFF_LOADER_IMAGE_CONTEXT *context,
+ UINT8 *sha256hash, UINT8 *sha1hash)
+{
+ EFI_STATUS efi_status;
+
+ efi_status = verify_buffer_sbat(data, datasize, context);
+ if (EFI_ERROR(efi_status))
+ return efi_status;
+
+ return verify_buffer_authenticode(data, datasize, context, sha256hash, sha1hash);
+}
+
static int
should_use_fallback(EFI_HANDLE image_handle)
{
@@ -1542,7 +1607,7 @@ efi_main (EFI_HANDLE passed_image_handle, EFI_SYSTEM_TABLE *passed_systab)
goto die;
}
- efi_status = handle_sbat(sbat_start, sbat_end - sbat_start - 1);
+ efi_status = verify_sbat_section(sbat_start, sbat_end - sbat_start - 1);
if (EFI_ERROR(efi_status)) {
perror(L"Verifiying shim SBAT data failed: %r\n",
efi_status);
--
2.27.0

Binary file not shown.

BIN
shim-15.6.tar.bz2 Normal file

Binary file not shown.

View File

@ -21,8 +21,8 @@
%global shimBOOT /boot/efi/EFI/BOOT/
Name: shim
Version: 15.4
Release: 5
Version: 15.6
Release: 1
Summary: First-stage UEFI bootloader
ExclusiveArch: x86_64 aarch64
License: BSD
@ -31,32 +31,18 @@ Source0: https://github.com/rhboot/shim/releases/download/%{version}/shim-%{v
Source1: BOOTAA64.CSV
Source2: BOOTX64.CSV
Patch0: backport-shim-another-attempt-to-fix-load-options-handling.patch
Patch1: backport-arm-aa64-fix-the-size-of-.rela-sections.patch
Patch2: backport-mok-relax-the-maximum-variable-size-check.patch
Patch3: backport-mok-delete-the-existing-RT-variables-only-when-only_.patch
Patch4: backport-shim-implement-SBAT-verification-for-the-shim_lock-p.patch
Patch5: backport-0001-CVE-2022-28737.patch
Patch6: backport-0002-CVE-2022-28737.patch
Patch7: backport-CVE-2017-3735.patch
Patch8: backport-CVE-2017-3737.patch
Patch9: backport-CVE-2018-0732.patch
Patch10: backport-Fix-an-endless-loop-in-rsa_builtin_keygen.patch
Patch11: backport-Replaced-variable-time-GCD-with-consttime-inversion.patch
Patch12: backport-consttime-flag-changed.patch
Patch13: backport-CVE-2018-0737.patch
Patch14: backport-CVE-2018-0739.patch
Patch15: backport-CVE-2019-1563.patch
Patch16: backport-0001-CVE-2020-1971.patch
Patch17: backport-0002-CVE-2020-1971.patch
Patch18: backport-0003-CVE-2020-1971.patch
Patch19: backport-0004-CVE-2020-1971.patch
Patch20: backport-make-update-EVP_F_EVP_DECRYPTUPDATE.patch
Patch21: backport-make-update-EVP_F_EVP_DECRYPTDECRYPTUPDATE.patch
Patch22: backport-CVE-2021-23840.patch
Patch23: backport-CVE-2021-23841.patch
Patch24: backport-CVE-2022-0778.patch
Patch25: backport-CVE-2021-3712.patch
Patch1:backport-CVE-2017-3735.patch
Patch2:backport-CVE-2017-3737.patch
Patch3:backport-CVE-2018-0732.patch
Patch4:backport-CVE-2018-0739.patch
Patch5:backport-CVE-2019-1563.patch
Patch6:backport-0001-CVE-2020-1971.patch
Patch7:backport-0002-CVE-2020-1971.patch
Patch8:backport-0003-CVE-2020-1971.patch
Patch9:backport-0004-CVE-2020-1971.patch
Patch10:backport-CVE-2021-23841.patch
Patch11:backport-CVE-2021-3712.patch
Patch12:backport-CVE-2022-0778.patch
BuildRequires: elfutils-libelf-devel openssl-devel openssl git pesign gnu-efi gnu-efi-devel gcc
Requires: dbxtool efi-filesystem mokutil
@ -153,9 +139,7 @@ cd ..
%files debuginfo
%defattr(-,root,root,-)
/usr/lib/debug/*
%ifarch x86_64
%exclude /usr/lib/debug/.build-id
%endif
%files debugsource
%defattr(-,root,root,-)
@ -163,6 +147,9 @@ cd ..
/usr/src/debug/%{name}-%{version}-%{release}/*
%changelog
* Mon Oct 31 2022 jinlun <jinlun@huawei.com> - 15.6-1
- update version to 15.6
* Tue Sep 20 2022 jinlun <jinlun@huawei.com> - 15.4-5
- fix CVE-2017-3735 CVE-2017-3737 CVE-2018-0732 CVE-2018-0737
CVE-2018-0739 CVE-2019-1563 CVE-2020-1971 CVE-2021-23840