Re: [PATCH] virtio-net: Add validation for used length

From: kernel test robot
Date: Tue May 25 2021 - 05:42:01 EST


Hi Xie,

Thank you for the patch! Perhaps something to improve:

[auto build test WARNING on linus/master]
[also build test WARNING on v5.13-rc3 next-20210525]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch]

url: https://github.com/0day-ci/linux/commits/Xie-Yongji/virtio-net-Add-validation-for-used-length/20210525-130449
base: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git a050a6d2b7e80ca52b2f4141eaf3420d201b72b3
config: x86_64-randconfig-a005-20210525 (attached as .config)
compiler: clang version 13.0.0 (https://github.com/llvm/llvm-project 99155e913e9bad5f7f8a247f8bb3a3ff3da74af1)
reproduce (this is a W=1 build):
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# install x86_64 cross compiling tool for clang build
# apt-get install binutils-x86-64-linux-gnu
# https://github.com/0day-ci/linux/commit/9cacb0e306acf93325699401dcae01f77505f017
git remote add linux-review https://github.com/0day-ci/linux
git fetch --no-tags linux-review Xie-Yongji/virtio-net-Add-validation-for-used-length/20210525-130449
git checkout 9cacb0e306acf93325699401dcae01f77505f017
# save the attached .config to linux build tree
COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=x86_64

If you fix the issue, kindly add following tag as appropriate
Reported-by: kernel test robot <lkp@xxxxxxxxx>

All warnings (new ones prefixed by >>):

>> drivers/net/virtio_net.c:740:22: warning: format specifies type 'unsigned long' but the argument has type 'int' [-Wformat]
dev->name, len, GOOD_PACKET_LEN);
^~~~~~~~~~~~~~~
include/linux/printk.h:424:26: note: expanded from macro 'pr_debug'
dynamic_pr_debug(fmt, ##__VA_ARGS__)
~~~ ^~~~~~~~~~~
include/linux/dynamic_debug.h:163:22: note: expanded from macro 'dynamic_pr_debug'
pr_fmt(fmt), ##__VA_ARGS__)
~~~ ^~~~~~~~~~~
include/linux/dynamic_debug.h:152:56: note: expanded from macro '_dynamic_func_call'
__dynamic_func_call(__UNIQUE_ID(ddebug), fmt, func, ##__VA_ARGS__)
^~~~~~~~~~~
include/linux/dynamic_debug.h:134:15: note: expanded from macro '__dynamic_func_call'
func(&id, ##__VA_ARGS__); \
^~~~~~~~~~~
drivers/net/virtio_net.c:35:25: note: expanded from macro 'GOOD_PACKET_LEN'
#define GOOD_PACKET_LEN (ETH_HLEN + VLAN_HLEN + ETH_DATA_LEN)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/net/virtio_net.c:820:21: warning: format specifies type 'unsigned long' but the argument has type 'int' [-Wformat]
dev->name, len, GOOD_PACKET_LEN);
^~~~~~~~~~~~~~~
include/linux/printk.h:424:26: note: expanded from macro 'pr_debug'
dynamic_pr_debug(fmt, ##__VA_ARGS__)
~~~ ^~~~~~~~~~~
include/linux/dynamic_debug.h:163:22: note: expanded from macro 'dynamic_pr_debug'
pr_fmt(fmt), ##__VA_ARGS__)
~~~ ^~~~~~~~~~~
include/linux/dynamic_debug.h:152:56: note: expanded from macro '_dynamic_func_call'
__dynamic_func_call(__UNIQUE_ID(ddebug), fmt, func, ##__VA_ARGS__)
^~~~~~~~~~~
include/linux/dynamic_debug.h:134:15: note: expanded from macro '__dynamic_func_call'
func(&id, ##__VA_ARGS__); \
^~~~~~~~~~~
drivers/net/virtio_net.c:35:25: note: expanded from macro 'GOOD_PACKET_LEN'
#define GOOD_PACKET_LEN (ETH_HLEN + VLAN_HLEN + ETH_DATA_LEN)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2 warnings generated.


vim +740 drivers/net/virtio_net.c

704
705 static struct sk_buff *receive_small(struct net_device *dev,
706 struct virtnet_info *vi,
707 struct receive_queue *rq,
708 void *buf, void *ctx,
709 unsigned int len,
710 unsigned int *xdp_xmit,
711 struct virtnet_rq_stats *stats)
712 {
713 struct sk_buff *skb;
714 struct bpf_prog *xdp_prog;
715 unsigned int xdp_headroom = (unsigned long)ctx;
716 unsigned int header_offset = VIRTNET_RX_PAD + xdp_headroom;
717 unsigned int headroom = vi->hdr_len + header_offset;
718 unsigned int buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
719 SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
720 struct page *page = virt_to_head_page(buf);
721 unsigned int delta = 0;
722 struct page *xdp_page;
723 int err;
724 unsigned int metasize = 0;
725
726 len -= vi->hdr_len;
727 stats->bytes += len;
728
729 rcu_read_lock();
730 xdp_prog = rcu_dereference(rq->xdp_prog);
731 if (xdp_prog) {
732 struct virtio_net_hdr_mrg_rxbuf *hdr = buf + header_offset;
733 struct xdp_frame *xdpf;
734 struct xdp_buff xdp;
735 void *orig_data;
736 u32 act;
737
738 if (unlikely(len > GOOD_PACKET_LEN)) {
739 pr_debug("%s: rx error: len %u exceeds max size %lu\n",
> 740 dev->name, len, GOOD_PACKET_LEN);
741 dev->stats.rx_length_errors++;
742 goto err_xdp;
743 }
744
745 if (unlikely(hdr->hdr.gso_type))
746 goto err_xdp;
747
748 if (unlikely(xdp_headroom < virtnet_get_headroom(vi))) {
749 int offset = buf - page_address(page) + header_offset;
750 unsigned int tlen = len + vi->hdr_len;
751 u16 num_buf = 1;
752
753 xdp_headroom = virtnet_get_headroom(vi);
754 header_offset = VIRTNET_RX_PAD + xdp_headroom;
755 headroom = vi->hdr_len + header_offset;
756 buflen = SKB_DATA_ALIGN(GOOD_PACKET_LEN + headroom) +
757 SKB_DATA_ALIGN(sizeof(struct skb_shared_info));
758 xdp_page = xdp_linearize_page(rq, &num_buf, page,
759 offset, header_offset,
760 &tlen);
761 if (!xdp_page)
762 goto err_xdp;
763
764 buf = page_address(xdp_page);
765 put_page(page);
766 page = xdp_page;
767 }
768
769 xdp_init_buff(&xdp, buflen, &rq->xdp_rxq);
770 xdp_prepare_buff(&xdp, buf + VIRTNET_RX_PAD + vi->hdr_len,
771 xdp_headroom, len, true);
772 orig_data = xdp.data;
773 act = bpf_prog_run_xdp(xdp_prog, &xdp);
774 stats->xdp_packets++;
775
776 switch (act) {
777 case XDP_PASS:
778 /* Recalculate length in case bpf program changed it */
779 delta = orig_data - xdp.data;
780 len = xdp.data_end - xdp.data;
781 metasize = xdp.data - xdp.data_meta;
782 break;
783 case XDP_TX:
784 stats->xdp_tx++;
785 xdpf = xdp_convert_buff_to_frame(&xdp);
786 if (unlikely(!xdpf))
787 goto err_xdp;
788 err = virtnet_xdp_xmit(dev, 1, &xdpf, 0);
789 if (unlikely(!err)) {
790 xdp_return_frame_rx_napi(xdpf);
791 } else if (unlikely(err < 0)) {
792 trace_xdp_exception(vi->dev, xdp_prog, act);
793 goto err_xdp;
794 }
795 *xdp_xmit |= VIRTIO_XDP_TX;
796 rcu_read_unlock();
797 goto xdp_xmit;
798 case XDP_REDIRECT:
799 stats->xdp_redirects++;
800 err = xdp_do_redirect(dev, &xdp, xdp_prog);
801 if (err)
802 goto err_xdp;
803 *xdp_xmit |= VIRTIO_XDP_REDIR;
804 rcu_read_unlock();
805 goto xdp_xmit;
806 default:
807 bpf_warn_invalid_xdp_action(act);
808 fallthrough;
809 case XDP_ABORTED:
810 trace_xdp_exception(vi->dev, xdp_prog, act);
811 goto err_xdp;
812 case XDP_DROP:
813 goto err_xdp;
814 }
815 }
816 rcu_read_unlock();
817
818 if (unlikely(len > GOOD_PACKET_LEN)) {
819 pr_debug("%s: rx error: len %u exceeds max size %lu\n",
820 dev->name, len, GOOD_PACKET_LEN);
821 dev->stats.rx_length_errors++;
822 put_page(page);
823 return NULL;
824 }
825
826 skb = build_skb(buf, buflen);
827 if (!skb) {
828 put_page(page);
829 goto err;
830 }
831 skb_reserve(skb, headroom - delta);
832 skb_put(skb, len);
833 if (!xdp_prog) {
834 buf += header_offset;
835 memcpy(skb_vnet_hdr(skb), buf, vi->hdr_len);
836 } /* keep zeroed vnet hdr since XDP is loaded */
837
838 if (metasize)
839 skb_metadata_set(skb, metasize);
840
841 err:
842 return skb;
843
844 err_xdp:
845 rcu_read_unlock();
846 stats->xdp_drops++;
847 stats->drops++;
848 put_page(page);
849 xdp_xmit:
850 return NULL;
851 }
852

---
0-DAY CI Kernel Test Service, Intel Corporation
https://lists.01.org/hyperkitty/list/kbuild-all@xxxxxxxxxxxx

Attachment: .config.gz
Description: application/gzip