All of lore.kernel.org
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Atish Patra" <atish.patra@linux.dev>
Cc: kvm@vger.kernel.org
Subject: Re: [PATCH v2 3/4] crypto: ccp: Fix possible deadlock in SEV init failure path
Date: Mon, 01 Jun 2026 23:41:58 +0000	[thread overview]
Message-ID: <20260601234159.0961C1F00898@smtp.kernel.org> (raw)
In-Reply-To: <20260601-sev_snp_fixes-v2-3-611891b28a86@meta.com>

Thank you for your contribution! Sashiko AI review found 5 potential issue(s) to consider:

Pre-existing issues:
- [High] Failure in snp_prep_cmd_buf permanently leaks the command buffer active state in __sev_do_cmd_locked, deadlocking the SEV interface.
- [High] sev_init_ex_buffer is allocated without zeroing, leaking uninitialized kernel memory to the host filesystem.
- [High] Unhandled allocation failure for dev_data->output in spdm_ctrl_alloc leads to passing a null physical address to the PSP firmware.
- [High] Retrying SEV-TIO commands after buffer expansion uses stale, freed physical addresses, leading to RMP violations.
- [High] Bounce buffer memory is permanently leaked when firmware page transitions fail during legacy SEV command preparation.
--

commit 1396d09c5ba264e4a091f5fa101bb062c384525c
Author: Atish Patra <atishp@meta.com>

crypto: ccp: Fix possible deadlock in SEV init failure path

__sev_platform_init_handle_init_ex_path() called
rmp_mark_pages_firmware() with locked=false but while the parent
function of init_ex_path already acquired the sev_cmd_mutex.
In case of a rmpupdate failure for any page after the first, the cleanup
path would invoke reclaim pages which would result in a deadlock in
sev_do_cmd.

Pass locked=true to honor the lock status of the parent function.

Fixes: 7364a6fbca45 ("crypto: ccp: Handle non-volatile INIT_EX data when SNP is enabled")
Reported-by: Chris Mason <clm@meta.com>
Assisted-by: Claude:claude-opus-4-6
Signed-off-by: Atish Patra <atishp@meta.com>

> diff --git a/drivers/crypto/ccp/sev-dev.c b/drivers/crypto/ccp/sev-dev.c
> index d1e9e0ac63b60..3d4793e8e34b2 100644
> --- a/drivers/crypto/ccp/sev-dev.c
> +++ b/drivers/crypto/ccp/sev-dev.c
> @@ -1557,7 +1557,7 @@ static int __sev_platform_init_handle_init_ex_path(struct sev_device *sev)
>  		unsigned long npages;
>  
>  		npages = 1UL << get_order(NV_LENGTH);
> -		if (rmp_mark_pages_firmware(__pa(sev_init_ex_buffer), npages, false)) {
> +		if (rmp_mark_pages_firmware(__pa(sev_init_ex_buffer), npages, true)) {
>  			dev_err(sev->dev, "SEV: INIT_EX NV memory page state change failed.\n");
>  			return -ENOMEM;
>  		}

[Severity: High]
This is a pre-existing issue, but does this allocation leak uninitialized
memory?

Looking at __sev_platform_init_handle_init_ex_path() in the same file:

drivers/crypto/ccp/sev-dev.c:__sev_platform_init_handle_init_ex_path() {
    ...
    page = alloc_pages(GFP_KERNEL, get_order(NV_LENGTH));
    ...
}

If the NV file does not exist, sev_read_init_ex_file() returns 0 without
writing any data. This leaves the 32KB buffer filled with uninitialized
kernel memory before transitioning to firmware state. When
sev_write_init_ex_file() later writes this buffer to the host filesystem,
could this persist kernel heap contents to disk if the firmware did not
fully overwrite it?

[Severity: High]
This is a pre-existing issue, but can this error path leave the command
buffer permanently active?

drivers/crypto/ccp/sev-dev.c:__sev_do_cmd_locked() {
    ...
    ret = snp_prep_cmd_buf(cmd, cmd_buf, desc_list);
    if (ret) {
        dev_err(sev->dev, "SEV: failed to prepare buffer...");
        return ret;
    }
    ...
}

Since sev->cmd_buf_active or sev->cmd_buf_backup_active were set to true
before this call, returning directly here bypasses resetting those flags.
Would this cause subsequent commands to fail with -EBUSY and lock up the
interface?

[Severity: High]
This is a pre-existing issue, but does this error path leak the mapped
bounce buffers?

drivers/crypto/ccp/sev-dev.c:snp_prep_cmd_buf() {
    ...
    if (sev_cmd_buf_writable(cmd)) {
        if (rmp_mark_pages_firmware(__pa(cmd_buf), 1, true))
            return -EFAULT;
    }
    ...
}

If this fails, it returns -EFAULT without calling
snp_unmap_cmd_buf_desc_list(), which appears to leave the mapped command
descriptors unmapped.

Similarly, in snp_map_cmd_buf_desc():

drivers/crypto/ccp/sev-dev.c:snp_map_cmd_buf_desc() {
    ...
    if (rmp_mark_pages_firmware(*desc->paddr_ptr, npages, true)) {
        pr_warn("Error moving pages to firmware-owned state...");
        return -EFAULT;
    }
    ...
}

If the firmware transition fails for an individual bounce buffer, the newly
allocated page isn't freed before returning -EFAULT. Could both of these
paths result in permanent memory leaks?

[Severity: High]
This is a pre-existing issue, but does this validation correctly check the
output buffer?

drivers/crypto/ccp/sev-dev-tio.c:spdm_ctrl_alloc() {
    ...
    dev_data->output = sla_alloc(dev_data->output_len, true);

    if (IS_SLA_NULL(dev_data->req) || IS_SLA_NULL(dev_data->resp) ||
        IS_SLA_NULL(dev_data->scratch) || IS_SLA_NULL(dev_data->dev_ctx)) {
    ...
}

The check examines dev_ctx instead of the newly allocated output. If the
output allocation fails, dev_data->output will be SLA_NULL (physical frame
number 0). Will returning success here cause the PSP firmware to use
physical page 0 as an output buffer and trigger an RMP violation?

[Severity: High]
This is a pre-existing issue, but does retrying the command use stale
physical addresses?

drivers/crypto/ccp/sev-dev-tio.c:sev_tio_do_cmd() {
    ...
    rc1 = sla_expand(&dev_data->output, &dev_data->output_len);
    ...
    rc = sev_do_cmd(cmd, data, psp_ret);
    ...
}

When sla_expand() allocates a new buffer and frees the old one, dev_data
pointers are updated. However, the data pointer passed to sev_do_cmd()
comes from the caller and contains a by-value copy of the old spdm_ctrl
fields. Will retrying the command pass the old, freed physical addresses
to the PSP firmware?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260601-sev_snp_fixes-v2-0-611891b28a86@meta.com?part=3

  reply	other threads:[~2026-06-01 23:41 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-01 23:04 [PATCH v2 0/4] KVM: Miscellaneous SEV/SNP related fixes Atish Patra
2026-06-01 23:04 ` [PATCH v2 1/4] KVM: SEV: Do not allow intra-host migration/mirroring of SNP VMs Atish Patra
2026-06-01 23:17   ` sashiko-bot
2026-06-02 21:55     ` Atish Patra
2026-06-03 13:08       ` Tom Lendacky
2026-06-02 14:38   ` Tom Lendacky
2026-06-02 18:44     ` Atish Patra
2026-06-01 23:04 ` [PATCH v2 2/4] KVM: selftests: Verify SNP VMs are rejected from migration and mirroring Atish Patra
2026-06-01 23:04 ` [PATCH v2 3/4] crypto: ccp: Fix possible deadlock in SEV init failure path Atish Patra
2026-06-01 23:41   ` sashiko-bot [this message]
2026-06-02 21:58     ` Atish Patra
2026-06-02 14:43   ` Tom Lendacky
2026-06-02 18:46     ` Atish Patra
2026-06-01 23:04 ` [PATCH v2 4/4] crypto: ccp: Fix memory leak in SEV INIT_EX path Atish Patra
2026-06-01 23:55   ` sashiko-bot
2026-06-02 19:08     ` Atish Patra
2026-06-02 14:54   ` Tom Lendacky
2026-06-02 18:17     ` Atish Patra

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260601234159.0961C1F00898@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=atish.patra@linux.dev \
    --cc=kvm@vger.kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.