Commit c5d24bdd authored by Haiyang Zhang's avatar Haiyang Zhang Committed by David S. Miller

hv_netvsc: Add range checking for rx packet offset and length

This patch adds range checking for rx packet offset and length.
It may only happen if there is a host side bug.
Signed-off-by: default avatarHaiyang Zhang <haiyangz@microsoft.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 5c71dadb
...@@ -793,6 +793,7 @@ struct netvsc_device { ...@@ -793,6 +793,7 @@ struct netvsc_device {
/* Receive buffer allocated by us but manages by NetVSP */ /* Receive buffer allocated by us but manages by NetVSP */
void *recv_buf; void *recv_buf;
u32 recv_buf_size; /* allocated bytes */
u32 recv_buf_gpadl_handle; u32 recv_buf_gpadl_handle;
u32 recv_section_cnt; u32 recv_section_cnt;
u32 recv_section_size; u32 recv_section_size;
......
...@@ -282,6 +282,8 @@ static int netvsc_init_buf(struct hv_device *device, ...@@ -282,6 +282,8 @@ static int netvsc_init_buf(struct hv_device *device,
goto cleanup; goto cleanup;
} }
net_device->recv_buf_size = buf_size;
/* /*
* Establish the gpadl handle for this buffer on this * Establish the gpadl handle for this buffer on this
* channel. Note: This call uses the vmbus connection rather * channel. Note: This call uses the vmbus connection rather
...@@ -1095,11 +1097,22 @@ static int netvsc_receive(struct net_device *ndev, ...@@ -1095,11 +1097,22 @@ static int netvsc_receive(struct net_device *ndev,
/* Each range represents 1 RNDIS pkt that contains 1 ethernet frame */ /* Each range represents 1 RNDIS pkt that contains 1 ethernet frame */
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
void *data = recv_buf u32 offset = vmxferpage_packet->ranges[i].byte_offset;
+ vmxferpage_packet->ranges[i].byte_offset;
u32 buflen = vmxferpage_packet->ranges[i].byte_count; u32 buflen = vmxferpage_packet->ranges[i].byte_count;
void *data;
int ret; int ret;
if (unlikely(offset + buflen > net_device->recv_buf_size)) {
status = NVSP_STAT_FAIL;
netif_err(net_device_ctx, rx_err, ndev,
"Packet offset:%u + len:%u too big\n",
offset, buflen);
continue;
}
data = recv_buf + offset;
trace_rndis_recv(ndev, q_idx, data); trace_rndis_recv(ndev, q_idx, data);
/* Pass it to the upper layer */ /* Pass it to the upper layer */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment