Re: [PATCH] x86/sme: Fix memory encryption if enabled by default and not overridden

From: Tom Lendacky
Date: Fri Jan 26 2024 - 17:27:05 EST


On 1/26/24 10:39, Ard Biesheuvel wrote:
From: Ard Biesheuvel <ardb@xxxxxxxxxx>

Commit cbebd68f59f0 ("x86/mm: Fix use of uninitialized buffer in
sme_enable()") 'fixed' an issue in sme_enable() detected by static
analysis, and broke the common case in the process.

cmdline_find_option() will return < 0 on an error, or when the command
line argument does not appear at all. In this particular case, the
latter is not an error condition, and so the early exit is wrong.

Instead, without mem_encrypt= on the command line, the compile time
default should be honoured, which could be to enable memory encryption,
and this is currently broken.

Fix it by setting sme_me_mask to a preliminary value based on the
compile time default, and only omitting the command line argument test
when cmdline_find_option() returns an error.

Cc: Borislav Petkov (AMD) <bp@xxxxxxxxx>
Cc: Tom Lendacky <thomas.lendacky@xxxxxxx>
Cc: Nikita Zhandarovich <n.zhandarovich@xxxxxxxxxx>
Cc: Kevin Loughlin <kevinloughlin@xxxxxxxxxx>
Fixes: cbebd68f59f0 ("x86/mm: Fix use of uninitialized buffer in sme_enable()")
Signed-off-by: Ard Biesheuvel <ardb@xxxxxxxxxx>

Nice catch.

Reviewed-by: Tom Lendacky <thomas.lendacky@xxxxxxx>

---
arch/x86/mm/mem_encrypt_identity.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/arch/x86/mm/mem_encrypt_identity.c b/arch/x86/mm/mem_encrypt_identity.c
index d73aeb16417f..30df4f1725f4 100644
--- a/arch/x86/mm/mem_encrypt_identity.c
+++ b/arch/x86/mm/mem_encrypt_identity.c
@@ -600,15 +600,14 @@ void __init sme_enable(struct boot_params *bp)
cmdline_ptr = (const char *)((u64)bp->hdr.cmd_line_ptr |
((u64)bp->ext_cmd_line_ptr << 32));
+ sme_me_mask = active_by_default ? me_mask : 0;
if (cmdline_find_option(cmdline_ptr, cmdline_arg, buffer, sizeof(buffer)) < 0)
- return;
+ goto out;
if (!strncmp(buffer, cmdline_on, sizeof(buffer)))
sme_me_mask = me_mask;
else if (!strncmp(buffer, cmdline_off, sizeof(buffer)))
sme_me_mask = 0;
- else
- sme_me_mask = active_by_default ? me_mask : 0;
out:
if (sme_me_mask) {
physical_mask &= ~sme_me_mask;