提交 066f3377 编写于 作者: A Andrea Parri (Microsoft) 提交者: Wei Liu

hv_sock: Copy packets sent by Hyper-V out of the ring buffer

Pointers to VMbus packets sent by Hyper-V are used by the hv_sock driver
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, copy the incoming packet after validating its
length and offset fields using hv_pkt_iter_{first,next}().  Use
HVS_PKT_LEN(HVS_MTU_SIZE) to initialize the buffer which holds the
copies of the incoming packets.  In this way, the packet can no longer
be modified by the host.
Signed-off-by: NAndrea Parri (Microsoft) <parri.andrea@gmail.com>
Reviewed-by: NMichael Kelley <mikelley@microsoft.com>
Reviewed-by: NStefano Garzarella <sgarzare@redhat.com>
Link: https://lore.kernel.org/r/20220428145107.7878-3-parri.andrea@gmail.comSigned-off-by: NWei Liu <wei.liu@kernel.org>
上级 71abb94f
...@@ -78,6 +78,9 @@ struct hvs_send_buf { ...@@ -78,6 +78,9 @@ struct hvs_send_buf {
ALIGN((payload_len), 8) + \ ALIGN((payload_len), 8) + \
VMBUS_PKT_TRAILER_SIZE) VMBUS_PKT_TRAILER_SIZE)
/* Upper bound on the size of a VMbus packet for hv_sock */
#define HVS_MAX_PKT_SIZE HVS_PKT_LEN(HVS_MTU_SIZE)
union hvs_service_id { union hvs_service_id {
guid_t srv_id; guid_t srv_id;
...@@ -378,6 +381,8 @@ static void hvs_open_connection(struct vmbus_channel *chan) ...@@ -378,6 +381,8 @@ static void hvs_open_connection(struct vmbus_channel *chan)
rcvbuf = ALIGN(rcvbuf, HV_HYP_PAGE_SIZE); rcvbuf = ALIGN(rcvbuf, HV_HYP_PAGE_SIZE);
} }
chan->max_pkt_size = HVS_MAX_PKT_SIZE;
ret = vmbus_open(chan, sndbuf, rcvbuf, NULL, 0, hvs_channel_cb, ret = vmbus_open(chan, sndbuf, rcvbuf, NULL, 0, hvs_channel_cb,
conn_from_host ? new : sk); conn_from_host ? new : sk);
if (ret != 0) { if (ret != 0) {
...@@ -602,7 +607,7 @@ static ssize_t hvs_stream_dequeue(struct vsock_sock *vsk, struct msghdr *msg, ...@@ -602,7 +607,7 @@ static ssize_t hvs_stream_dequeue(struct vsock_sock *vsk, struct msghdr *msg,
return -EOPNOTSUPP; return -EOPNOTSUPP;
if (need_refill) { if (need_refill) {
hvs->recv_desc = hv_pkt_iter_first_raw(hvs->chan); hvs->recv_desc = hv_pkt_iter_first(hvs->chan);
if (!hvs->recv_desc) if (!hvs->recv_desc)
return -ENOBUFS; return -ENOBUFS;
ret = hvs_update_recv_data(hvs); ret = hvs_update_recv_data(hvs);
...@@ -618,7 +623,7 @@ static ssize_t hvs_stream_dequeue(struct vsock_sock *vsk, struct msghdr *msg, ...@@ -618,7 +623,7 @@ static ssize_t hvs_stream_dequeue(struct vsock_sock *vsk, struct msghdr *msg,
hvs->recv_data_len -= to_read; hvs->recv_data_len -= to_read;
if (hvs->recv_data_len == 0) { if (hvs->recv_data_len == 0) {
hvs->recv_desc = hv_pkt_iter_next_raw(hvs->chan, hvs->recv_desc); hvs->recv_desc = hv_pkt_iter_next(hvs->chan, hvs->recv_desc);
if (hvs->recv_desc) { if (hvs->recv_desc) {
ret = hvs_update_recv_data(hvs); ret = hvs_update_recv_data(hvs);
if (ret) if (ret)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册