Haiyang Zhang <haiyangz@xxxxxxxxxxxxxxxxx> writes: > From: Haiyang Zhang <haiyangz@xxxxxxxxxxxxx> > > 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: Haiyang Zhang <haiyangz@xxxxxxxxxxxxx> > --- > drivers/net/hyperv/hyperv_net.h | 1 + > drivers/net/hyperv/netvsc.c | 17 +++++++++++++++-- > 2 files changed, 16 insertions(+), 2 deletions(-) > > diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h > index 0db3bd1ea06f..49c05ac894e5 100644 > --- a/drivers/net/hyperv/hyperv_net.h > +++ b/drivers/net/hyperv/hyperv_net.h > @@ -793,6 +793,7 @@ struct netvsc_device { > > /* Receive buffer allocated by us but manages by NetVSP */ > void *recv_buf; > + u32 recv_buf_size; /* allocated bytes */ > u32 recv_buf_gpadl_handle; > u32 recv_section_cnt; > u32 recv_section_size; > diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c > index 1ddb2c39b6e4..a6700d65f206 100644 > --- a/drivers/net/hyperv/netvsc.c > +++ b/drivers/net/hyperv/netvsc.c > @@ -289,6 +289,8 @@ static int netvsc_init_buf(struct hv_device *device, > goto cleanup; > } > > + net_device->recv_buf_size = buf_size; > + > /* > * Establish the gpadl handle for this buffer on this > * channel. Note: This call uses the vmbus connection rather > @@ -1095,11 +1097,22 @@ static int netvsc_receive(struct net_device *ndev, > > /* Each range represents 1 RNDIS pkt that contains 1 ethernet frame */ > for (i = 0; i < count; i++) { > - void *data = recv_buf > - + vmxferpage_packet->ranges[i].byte_offset; > + u32 offset = vmxferpage_packet->ranges[i].byte_offset; > u32 buflen = vmxferpage_packet->ranges[i].byte_count; > + void *data; > 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); This shouldn't happen, of course, but I'd rather ratelimit this error or even used something like netdev_WARN_ONCE(). > + > + continue; > + } > + > + data = recv_buf + offset; > + > trace_rndis_recv(ndev, q_idx, data); > > /* Pass it to the upper layer */ -- Vitaly _______________________________________________ devel mailing list devel@xxxxxxxxxxxxxxxxxxxxxx http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel