From: Andrea Parri <parri.andrea@gmail.com>
To: "Michael Kelley (LINUX)" <mikelley@microsoft.com>
Cc: KY Srinivasan <kys@microsoft.com>,
Haiyang Zhang <haiyangz@microsoft.com>,
Stephen Hemminger <sthemmin@microsoft.com>,
Wei Liu <wei.liu@kernel.org>, Dexuan Cui <decui@microsoft.com>,
Wei Hu <weh@microsoft.com>,
Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>,
Rob Herring <robh@kernel.org>,
Krzysztof Wilczynski <kw@linux.com>,
Bjorn Helgaas <bhelgaas@google.com>,
"linux-pci@vger.kernel.org" <linux-pci@vger.kernel.org>,
"linux-hyperv@vger.kernel.org" <linux-hyperv@vger.kernel.org>,
"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH 1/2] PCI: hv: Use IDR to generate transaction IDs for VMBus hardening
Date: Tue, 22 Mar 2022 13:51:22 +0100 [thread overview]
Message-ID: <20220322125122.GA2158@anparri> (raw)
In-Reply-To: <PH0PR21MB3025C19EDC8F5230DB1957EBD7169@PH0PR21MB3025.namprd21.prod.outlook.com>
> > I think I should elaborate on the design underlying this submission;
> > roughly, the present solution diverges from the 'generic' requestor
> > mechanism you mentioned above in two main aspects:
> >
> > A) it 'moves' the ID removal into hv_compose_msi_msg() and other
> > functions,
>
> Right. A key implication is that this patch allows the completion
> function to be called multiple times, if Hyper-V were to be malicious
> and send multiple responses with the same requestID. This is OK as
> long as the completion functions are idempotent, which after looking,
> I think they are in this driver.
>
> Furthermore, this patch allows the completion function to run anytime
> between when the requestID is created and when it is deleted. This
> patch creates the requestID just before calling vmbus_sendpacket(),
> which is good. The requestID is deleted later in the various functions.
> I saw only one potential problem, which is in new_pcichild_device(),
> where the new hpdev is added to a global list before the requestID is
> deleted. There's a window where the completion function could run
> and update the probed_bar[] values asynchronously after the hpdev is
> on the global list. I don't know if this is a problem or not, but it could
> be prevented by deleting the requestID a little earlier in the function.
>
> >
> > B) it adopts some ad-hoc locking scheme in the channel callback.
> >
> > AFAICT, such changes preserve the 'confidentiality' and correctness
> > guarantees of the generic approach (modulo the issue discussed here
> > with Saurabh).
>
> Yes, I agree, assuming the current functionality of the completion
> functions.
>
> >
> > These changes are justified by the bug/fix discussed in 2/2. For
> > concreteness, consider a solution based on the VMbus requestor as
> > reported at the end of this email.
> >
> > AFAICT, this solution can't fix the bug discussed in 2/2. Moreover
> > (and looking back at (A-B)), we observe that:
> >
> > 1) locking in the channel callback is not quite as desired: we'd
> > want a request_addr_callback_nolock() say and 'protected' it
> > together with ->completion_func();
>
> I'm not understanding this point. Could you clarify?
Basically (on top of the previous diff):
@@ -2700,6 +2725,7 @@ static void hv_pci_onchannelcallback(void *context)
int ret;
struct hv_pcibus_device *hbus = context;
struct vmbus_channel *chan = hbus->hdev->channel;
+ struct vmbus_requestor *rqstor = &chan->requestor;
u32 bytes_recvd;
u64 req_id, req_addr;
struct vmpacket_descriptor *desc;
@@ -2713,6 +2739,7 @@ static void hv_pci_onchannelcallback(void *context)
struct pci_dev_inval_block *inval;
struct pci_dev_incoming *dev_message;
struct hv_pci_dev *hpdev;
+ unsigned long flags;
buffer = kmalloc(bufferlen, GFP_ATOMIC);
if (!buffer)
@@ -2747,8 +2774,10 @@ static void hv_pci_onchannelcallback(void *context)
switch (desc->type) {
case VM_PKT_COMP:
- req_addr = chan->request_addr_callback(chan, req_id);
+ spin_lock_irqsave(&rqstor->req_lock, flags);
+ req_addr = __hv_pci_request_addr(chan, req_id);
if (!req_addr || req_addr == VMBUS_RQST_ERROR) {
+ spin_unlock_irqrestore(&rqstor->req_lock, flags);
dev_warn_ratelimited(&hbus->hdev->device,
"Invalid request ID\n");
break;
@@ -2758,6 +2787,7 @@ static void hv_pci_onchannelcallback(void *context)
comp_packet->completion_func(comp_packet->compl_ctxt,
response,
bytes_recvd);
+ spin_unlock_irqrestore(&rqstor->req_lock, flags);
break;
case VM_PKT_DATA_INBAND:
where I renamed request_addr_callback_nolock() to __hv_pci_request_addr()
(this being as in vmbus_request_addr() but without the requestor lock).
A "locked" callback would still be wanted and used in, e.g., the failure
path of hv_ringbuffer_write().
> > 2) hv_compose_msi_msg() doesn't know the value of the request ID
> > it has allocated (hv_compose_msi_msg() -> vmbus_sendpacket();
> > cf. also remove_request_id() in the current submission).
>
> Agreed. This would have to be addressed by adding another version of
> vmbus_sendpacket() that returns the request ID.
Indeed... Some care would be needed to make sure that that "ID removal"
can't "race" with hv_pci_onchannelcallback() (which could have removed
the ID now), but yes...
> > Hope this helps clarify the problems at stake, and move forward to a
> > 'final' solution...
>
> I think there's a reasonable way for the vmbus_next_request_id()
> mechanism to solve the problem in Patch 2/2 (if a new version of
> vmbus_sendpacket is added). To me, that mechanism seems safer
> in that it restricts the completion function to running just once
> per requestID. With this patch, we must remember that the
> completion functions must remain idempotent.
Fair enough. Thank you for bearing with me and patiently reviewing these
matters. Working out the details...
Thanks,
Andrea
next prev parent reply other threads:[~2022-03-22 12:51 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-03-18 17:48 [PATCH 0/2] PCI: hv: Miscellaneous changes Andrea Parri (Microsoft)
2022-03-18 17:48 ` [PATCH 1/2] PCI: hv: Use IDR to generate transaction IDs for VMBus hardening Andrea Parri (Microsoft)
2022-03-19 7:47 ` [EXTERNAL] " Saurabh Singh Sengar
2022-03-19 15:59 ` Andrea Parri
2022-03-20 5:53 ` Saurabh Singh Sengar
2022-03-19 16:20 ` Michael Kelley (LINUX)
2022-03-20 14:58 ` Andrea Parri
2022-03-21 18:23 ` Michael Kelley (LINUX)
2022-03-22 12:51 ` Andrea Parri [this message]
2022-03-18 17:48 ` [PATCH 2/2] PCI: hv: Fix synchronization between channel callback and hv_compose_msi_msg() Andrea Parri (Microsoft)
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=20220322125122.GA2158@anparri \
--to=parri.andrea@gmail.com \
--cc=bhelgaas@google.com \
--cc=decui@microsoft.com \
--cc=haiyangz@microsoft.com \
--cc=kw@linux.com \
--cc=kys@microsoft.com \
--cc=linux-hyperv@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=lorenzo.pieralisi@arm.com \
--cc=mikelley@microsoft.com \
--cc=robh@kernel.org \
--cc=sthemmin@microsoft.com \
--cc=weh@microsoft.com \
--cc=wei.liu@kernel.org \
/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