On Mon, Mar 15, 2021 at 4:52 PM Xiao Wang <xiao.w.w...@intel.com> wrote: > > When parsing the virtio net header and packet header for dequeue offload, > we need to perform sanity check on the packet header to ensure: > - No out-of-boundary memory access. > - The packet header and virtio_net header are valid and aligned. > > Fixes: d0cf91303d73 ("vhost: add Tx offload capabilities") > Cc: sta...@dpdk.org > > Signed-off-by: Xiao Wang <xiao.w.w...@intel.com> > --- > v2: > Allow empty L4 payload for cksum offload. > --- > lib/librte_vhost/virtio_net.c | 49 > +++++++++++++++++++++++++++++++++++++------ > 1 file changed, 43 insertions(+), 6 deletions(-) > > diff --git a/lib/librte_vhost/virtio_net.c b/lib/librte_vhost/virtio_net.c > index 583bf379c6..53a8ff2898 100644 > --- a/lib/librte_vhost/virtio_net.c > +++ b/lib/librte_vhost/virtio_net.c > @@ -1821,44 +1821,64 @@ virtio_net_with_host_offload(struct virtio_net *dev) > return false; > } > > -static void > -parse_ethernet(struct rte_mbuf *m, uint16_t *l4_proto, void **l4_hdr) > +static int > +parse_ethernet(struct rte_mbuf *m, uint16_t *l4_proto, void **l4_hdr, > + uint16_t *len) > { > struct rte_ipv4_hdr *ipv4_hdr; > struct rte_ipv6_hdr *ipv6_hdr; > void *l3_hdr = NULL; > struct rte_ether_hdr *eth_hdr; > uint16_t ethertype; > + uint16_t data_len = m->data_len;
> > eth_hdr = rte_pktmbuf_mtod(m, struct rte_ether_hdr *); > > + if (data_len <= sizeof(struct rte_ether_hdr)) > + return -EINVAL; On principle, the check should happen before calling rte_pktmbuf_mtod, like what rte_pktmbuf_read does. Looking at the rest of the patch, does this helper function only handle mono segment mbufs? My reading of copy_desc_to_mbuf() was that it could generate multi segments mbufs... [snip] > case RTE_ETHER_TYPE_IPV4: > + if (data_len <= sizeof(struct rte_ipv4_hdr)) > + return -EINVAL; > ipv4_hdr = l3_hdr; > *l4_proto = ipv4_hdr->next_proto_id; > m->l3_len = rte_ipv4_hdr_len(ipv4_hdr); > + if (data_len <= m->l3_len) { > + m->l3_len = 0; > + return -EINVAL; > + } ... so here, comparing l3 length to only the first segment length (data_len) would be invalid. If this helper must deal with multi segments, why not use rte_pktmbuf_read? This function returns access to mbuf data after checking offset and length are contiguous, else copy the needed data in a passed buffer. > *l4_hdr = (char *)l3_hdr + m->l3_len; > m->ol_flags |= PKT_TX_IPV4; > + data_len -= m->l3_len; > break; -- David Marchand