mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-07-22 23:04:43 +00:00
Drivers: hv: vmbus: Copy packets sent by Hyper-V out of the ring buffer
Pointers to ring-buffer packets sent by Hyper-V are used within the guest VM. Hyper-V can send packets with erroneous values or modify packet fields after they are processed by the guest. To defend against these scenarios, return a copy of the incoming VMBus packet after validating its length and offset fields in hv_pkt_iter_first(). In this way, the packet can no longer be modified by the host. Signed-off-by: Andres Beltran <lkmlabelt@gmail.com> Co-developed-by: Andrea Parri (Microsoft) <parri.andrea@gmail.com> Signed-off-by: Andrea Parri (Microsoft) <parri.andrea@gmail.com> Reviewed-by: Michael Kelley <mikelley@microsoft.com> Link: https://lore.kernel.org/r/20210408161439.341988-1-parri.andrea@gmail.com Signed-off-by: Wei Liu <wei.liu@kernel.org>
This commit is contained in:
parent
03b30cc38d
commit
adae1e931a
11 changed files with 143 additions and 25 deletions
|
@ -181,6 +181,10 @@ struct hv_ring_buffer_info {
|
|||
* being freed while the ring buffer is being accessed.
|
||||
*/
|
||||
struct mutex ring_buffer_mutex;
|
||||
|
||||
/* Buffer that holds a copy of an incoming host packet */
|
||||
void *pkt_buffer;
|
||||
u32 pkt_buffer_size;
|
||||
};
|
||||
|
||||
|
||||
|
@ -799,6 +803,8 @@ struct vmbus_device {
|
|||
bool allowed_in_isolated;
|
||||
};
|
||||
|
||||
#define VMBUS_DEFAULT_MAX_PKT_SIZE 4096
|
||||
|
||||
struct vmbus_channel {
|
||||
struct list_head listentry;
|
||||
|
||||
|
@ -1021,6 +1027,9 @@ struct vmbus_channel {
|
|||
/* request/transaction ids for VMBus */
|
||||
struct vmbus_requestor requestor;
|
||||
u32 rqstor_size;
|
||||
|
||||
/* The max size of a packet on this channel */
|
||||
u32 max_pkt_size;
|
||||
};
|
||||
|
||||
u64 vmbus_next_request_id(struct vmbus_requestor *rqstor, u64 rqst_addr);
|
||||
|
@ -1662,15 +1671,44 @@ static inline u32 hv_pkt_datalen(const struct vmpacket_descriptor *desc)
|
|||
}
|
||||
|
||||
|
||||
struct vmpacket_descriptor *
|
||||
hv_pkt_iter_first_raw(struct vmbus_channel *channel);
|
||||
|
||||
struct vmpacket_descriptor *
|
||||
hv_pkt_iter_first(struct vmbus_channel *channel);
|
||||
|
||||
struct vmpacket_descriptor *
|
||||
__hv_pkt_iter_next(struct vmbus_channel *channel,
|
||||
const struct vmpacket_descriptor *pkt);
|
||||
const struct vmpacket_descriptor *pkt,
|
||||
bool copy);
|
||||
|
||||
void hv_pkt_iter_close(struct vmbus_channel *channel);
|
||||
|
||||
static inline struct vmpacket_descriptor *
|
||||
hv_pkt_iter_next_pkt(struct vmbus_channel *channel,
|
||||
const struct vmpacket_descriptor *pkt,
|
||||
bool copy)
|
||||
{
|
||||
struct vmpacket_descriptor *nxt;
|
||||
|
||||
nxt = __hv_pkt_iter_next(channel, pkt, copy);
|
||||
if (!nxt)
|
||||
hv_pkt_iter_close(channel);
|
||||
|
||||
return nxt;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get next packet descriptor without copying it out of the ring buffer
|
||||
* If at end of list, return NULL and update host.
|
||||
*/
|
||||
static inline struct vmpacket_descriptor *
|
||||
hv_pkt_iter_next_raw(struct vmbus_channel *channel,
|
||||
const struct vmpacket_descriptor *pkt)
|
||||
{
|
||||
return hv_pkt_iter_next_pkt(channel, pkt, false);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get next packet descriptor from iterator
|
||||
* If at end of list, return NULL and update host.
|
||||
|
@ -1679,13 +1717,7 @@ static inline struct vmpacket_descriptor *
|
|||
hv_pkt_iter_next(struct vmbus_channel *channel,
|
||||
const struct vmpacket_descriptor *pkt)
|
||||
{
|
||||
struct vmpacket_descriptor *nxt;
|
||||
|
||||
nxt = __hv_pkt_iter_next(channel, pkt);
|
||||
if (!nxt)
|
||||
hv_pkt_iter_close(channel);
|
||||
|
||||
return nxt;
|
||||
return hv_pkt_iter_next_pkt(channel, pkt, true);
|
||||
}
|
||||
|
||||
#define foreach_vmbus_pkt(pkt, channel) \
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue