Linux Confidential Computing Development
 help / color / mirror / Atom feed
From: Alexey Kardashevskiy <aik@amd.com>
To: Dan Williams <dan.j.williams@intel.com>, linux-coco@lists.linux.dev
Cc: Borislav Petkov <bp@alien8.de>,
	Tom Lendacky <thomas.lendacky@amd.com>,
	Dionna Glaze <dionnaglaze@google.com>,
	Brijesh Singh <brijesh.singh@amd.com>,
	Jeremi Piotrowski <jpiotrowski@linux.microsoft.com>,
	Kuppuswamy Sathyanarayanan
	<sathyanarayanan.kuppuswamy@linux.intel.com>,
	peterz@infradead.org, dave.hansen@linux.intel.com
Subject: Re: [PATCH v6 6/7] virt: sevguest: Add TSM_REPORTS support for SNP_GET_EXT_REPORT
Date: Thu, 19 Oct 2023 16:12:35 +1100	[thread overview]
Message-ID: <e83612b5-35ed-427d-9d2c-f502a9c7e4c2@amd.com> (raw)
In-Reply-To: <6530b3fda1e2d_5c0d29451@dwillia2-mobl3.amr.corp.intel.com.notmuch>


On 19/10/23 15:43, Dan Williams wrote:
> Alexey Kardashevskiy wrote:
> [..]
>>> Yes, it's been allowed in loop declaration for a few kernels now and the
>>> new __free() helper in cleanup.h will make this model more prominent. My
>>> sense is that it is still not open season on mid-function declarations,
>>> but __attribute__((__cleanup__())) usage needs it.
>>>
>>>> Since you are doing this, move zero_ent below. Or, better, use
>>>> guid_is_null().
>>>
>>> guid_is_null() is not techinically enough given the specification
>>> mandates that the entire entry is zero.
>>
>> Well technically it says that guid, offset and length must be zeroes.
>> So, (guid_is_null() && !offset && !length) and no yet another static
>> declaration of a bunch of zeroes far away. I even wonder if there is a
>> helper to check if some memory is all zeroes :) Up to you.
> 
> Ok, I switched to comparing each field to zero.
> 
> [..]
>>>>> +	if (ret)
>>>>> +		return ret;
>>>>> +
>>>>> +	memcpy(&hdr, buf, sizeof(hdr));
>>>>> +	if (hdr.status == SNP_REPORT_INVALID_PARAM)
>>>>> +		return -EINVAL;
>>>>> +	if (hdr.status == SNP_REPORT_INVALID_KEY_SEL)
>>>>> +		return -EINVAL;
>>>>> +	if (hdr.status)
>>>>> +		return -ENXIO;
>>>>> +	if ((hdr.report_size + sizeof(hdr)) > report_size)
>>>>> +		return -ENOMEM;
>>>>> +
>>>>> +	void *rbuf __free(kvfree) = kvzalloc(hdr.report_size, GFP_KERNEL);
>>>>> +	if (!rbuf)
>>>>> +		return -ENOMEM;
>>>>> +
>>>>> +	memcpy(rbuf, buf + sizeof(hdr), hdr.report_size);
>>>>> +	report->outblob = no_free_ptr(rbuf);
>>>>> +	report->outblob_len = hdr.report_size;
>>>>> +
>>>>> +	certs_size = 0;
>>>>> +	for (i = 0; i < ext_size / sizeof(struct snp_msg_cert_entry); i++) {
>>>>> +		if (memcmp(&cert_table[i], &zero_ent, sizeof(zero_ent)) == 0)
>>>>> +			break;
>>>>> +		certs_size = max(certs_size, cert_table[i].offset + cert_table[i].length);
>>>>> +	}
>>>>> +
>>>>> +	/* No certs to report */
>>>>> +	if (!certs_size)
>>>>
>>>> Nit: WARN_ON_ONCE(i) here?
>>>
>>> Seems harsh for what could only be a firmware bug, panic_on_warn users
>>> would not appreciate crashing the kernel over something recoverable like
>>> this.
>>
>> This would a HV bug as certificates come from the KVM. And it is
>> (slightly) more likely that the HV is trying to trigger buffer overrun
>> in the guest.
> 
> Added a dev_warn_ratelimited(). WARN_ON_ONCE() is too heavy as I expect
> panic_on_warn policy has more reason to be deployed in a confidential VM
> than other places. >>>>
>>>>> +		return 0;
>>>>> +
>>>>> +	/*
>>>>> +	 * cert_table reports more data than fits in ext_size the
>>>>> +	 * userspace cert_table walker can decide what happens next,
>>>>> +	 * truncate the output
>>>>> +	 */
>>>>> +	if (certs_size > ext_size)
>>>>> +		certs_size = ext_size;
>>>>
>>>> This sounds more like the HV provided a broken table with offset(s)
>>>> ouside of the certs buffer. The HV is expected instead return
>>>> SW_EXITINFO2=0x0000000100000000 and RBX=requred_pages_number, and the
>>>> guest to retry.
>>>
>>> The existence of SEV_FW_BLOB_MAX_SIZE suggests the driver is not
>>> prepared to retry. Retry support would be a follow-on new capability.
>>
>> My point is that you should not get into the situation when this
>> calculated certs_size is greater than ext_size. If this is the case
>> because someone sent too many certificaties via /dev/sev or kvmfd on the
>> host, the GHCB call won't return any certs and will ask for a retry instead.
> 
> I understand, but given this needs to walk the entries anyway to size
> the buffer correctly this sanity check is "free".

I do not mind the check at all but this hides a potential bug or 
malicious misbehavior attempt. I'd think a CoCo VM is very paranoid 
about such things.


>>>>> +
>>>>> +	void *cbuf __free(kvfree) = kvzalloc(certs_size, GFP_KERNEL);
>>>>> +	if (!cbuf)
>>>>> +		return -ENOMEM;
>>>>
>>>> In a such (unlikely) event the function returns an error but does not
>>>> free report->outblob which is going to leak if consequent call succeded.
>>>> This new no_free_ptr business is confusing at times :(
>>>
>>> If this fails it results in the attribute read failing and
>>> read_generation does not advance. The next read attempt will free the
>>> partially completed report and retry,
>>
>> Ah ok. In general, it just feels like every use of no_free_ptr() defeats
>> the whole purpose of __free(xxx).
> 
> no_free_ptr() is there to say "we correctly populated this buffer,
> there are no more error returns in this function, transition the
> responsibility of freeing this buffer to the object it was assigned".


That's what I thought but there is one error return between the first 
no_free_ptr() and "return 0". I agree there is no outblob leak after all 
but the blob hangs around for some time and all this __free() machinery 
is supposed to auto-clean everything right on the spot before returning 
-ENOMEM. Grouping all these no_free_ptr() in the end would make it 
cleaner... Again, I do not insist.

And btw thanks for doing this! I never liked those ioctls :)


-- 
Alexey



  reply	other threads:[~2023-10-19  5:12 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2023-10-13  2:13 [PATCH v6 0/7] configfs-tsm: Attestation Report ABI Dan Williams
2023-10-13  2:14 ` [PATCH v6 1/7] virt: sevguest: Fix passing a stack buffer as a scatterlist target Dan Williams
2023-10-13  2:14 ` [PATCH v6 2/7] virt: coco: Add a coco/Makefile and coco/Kconfig Dan Williams
2023-10-13  2:14 ` [PATCH v6 3/7] configfs-tsm: Introduce a shared ABI for attestation reports Dan Williams
2023-10-13  4:43   ` Dionna Amalie Glaze
2023-10-13  5:15     ` Dan Williams
2023-10-16  6:36   ` Alexey Kardashevskiy
2023-10-17  2:19     ` Dan Williams
2023-10-17  6:20       ` Alexey Kardashevskiy
2023-10-19  1:29         ` Dan Williams
2023-10-19 20:24         ` Dan Williams
2023-10-13  2:14 ` [PATCH v6 4/7] virt: sevguest: Prep for kernel internal get_ext_report() Dan Williams
2023-10-13  2:14 ` [PATCH v6 5/7] mm/slab: Add __free() support for kvfree Dan Williams
2023-10-13  2:14 ` [PATCH v6 6/7] virt: sevguest: Add TSM_REPORTS support for SNP_GET_EXT_REPORT Dan Williams
2023-10-13 15:38   ` Tom Lendacky
2023-10-14  4:46     ` Dan Williams
2023-10-16 11:36   ` Alexey Kardashevskiy
2023-10-16 15:39     ` Dionna Amalie Glaze
2023-10-16 15:42       ` Peter Gonda
2023-10-17  0:42         ` Alexey Kardashevskiy
2023-10-19  4:30           ` Dan Williams
2023-10-17  4:07     ` Dan Williams
2023-10-17  5:35       ` Alexey Kardashevskiy
2023-10-17  6:28         ` Alexey Kardashevskiy
2023-10-19  4:43         ` Dan Williams
2023-10-19  5:12           ` Alexey Kardashevskiy [this message]
2023-10-19  3:34     ` Dan Williams
2023-10-13  2:14 ` [PATCH v6 7/7] virt: tdx-guest: Add Quote generation support using TSM_REPORTS Dan Williams
2023-10-19 18:12   ` Peter Gonda
2023-10-13 15:39 ` [PATCH v6 0/7] configfs-tsm: Attestation Report ABI Tom Lendacky

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=e83612b5-35ed-427d-9d2c-f502a9c7e4c2@amd.com \
    --to=aik@amd.com \
    --cc=bp@alien8.de \
    --cc=brijesh.singh@amd.com \
    --cc=dan.j.williams@intel.com \
    --cc=dave.hansen@linux.intel.com \
    --cc=dionnaglaze@google.com \
    --cc=jpiotrowski@linux.microsoft.com \
    --cc=linux-coco@lists.linux.dev \
    --cc=peterz@infradead.org \
    --cc=sathyanarayanan.kuppuswamy@linux.intel.com \
    --cc=thomas.lendacky@amd.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox