Hi Denis,

kernel test robot noticed the following build warnings:

[auto build test WARNING on linus/master]
[also build test WARNING on v6.10-rc2 next-20240607]
[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#_base_tree_information]

url:    
https://github.com/intel-lab-lkp/linux/commits/Denis-Arefev/net-missing-check/20240606-230540
base:   linus/master
patch link:    
https://lore.kernel.org/r/20240606141450.44709-1-arefev%40swemel.ru
patch subject: [PATCH] net: missing check
config: x86_64-randconfig-121-20240607 
(https://download.01.org/0day-ci/archive/20240607/202406071404.oilhfohm-...@intel.com/config)
compiler: gcc-13 (Ubuntu 13.2.0-4ubuntu3) 13.2.0
reproduce (this is a W=1 build): 
(https://download.01.org/0day-ci/archive/20240607/202406071404.oilhfohm-...@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <l...@intel.com>
| Closes: 
https://lore.kernel.org/oe-kbuild-all/202406071404.oilhfohm-...@intel.com/

sparse warnings: (new ones prefixed by >>)
   drivers/net/virtio_net.c: note: in included file:
>> include/linux/virtio_net.h:103:58: sparse: sparse: incorrect type in 
>> argument 2 (different base types) @@     expected unsigned long long 
>> [usertype] divisor @@     got restricted __virtio16 const [usertype] 
>> gso_size @@
   include/linux/virtio_net.h:103:58: sparse:     expected unsigned long long 
[usertype] divisor
   include/linux/virtio_net.h:103:58: sparse:     got restricted __virtio16 
const [usertype] gso_size
>> include/linux/virtio_net.h:104:42: sparse: sparse: restricted __virtio16 
>> degrades to integer

vim +103 include/linux/virtio_net.h

    49  
    50  static inline int virtio_net_hdr_to_skb(struct sk_buff *skb,
    51                                          const struct virtio_net_hdr 
*hdr,
    52                                          bool little_endian)
    53  {
    54          unsigned int nh_min_len = sizeof(struct iphdr);
    55          unsigned int gso_type = 0;
    56          unsigned int thlen = 0;
    57          unsigned int p_off = 0;
    58          unsigned int ip_proto;
    59          u64 ret, remainder;
    60  
    61          if (hdr->gso_type != VIRTIO_NET_HDR_GSO_NONE) {
    62                  switch (hdr->gso_type & ~VIRTIO_NET_HDR_GSO_ECN) {
    63                  case VIRTIO_NET_HDR_GSO_TCPV4:
    64                          gso_type = SKB_GSO_TCPV4;
    65                          ip_proto = IPPROTO_TCP;
    66                          thlen = sizeof(struct tcphdr);
    67                          break;
    68                  case VIRTIO_NET_HDR_GSO_TCPV6:
    69                          gso_type = SKB_GSO_TCPV6;
    70                          ip_proto = IPPROTO_TCP;
    71                          thlen = sizeof(struct tcphdr);
    72                          nh_min_len = sizeof(struct ipv6hdr);
    73                          break;
    74                  case VIRTIO_NET_HDR_GSO_UDP:
    75                          gso_type = SKB_GSO_UDP;
    76                          ip_proto = IPPROTO_UDP;
    77                          thlen = sizeof(struct udphdr);
    78                          break;
    79                  case VIRTIO_NET_HDR_GSO_UDP_L4:
    80                          gso_type = SKB_GSO_UDP_L4;
    81                          ip_proto = IPPROTO_UDP;
    82                          thlen = sizeof(struct udphdr);
    83                          break;
    84                  default:
    85                          return -EINVAL;
    86                  }
    87  
    88                  if (hdr->gso_type & VIRTIO_NET_HDR_GSO_ECN)
    89                          gso_type |= SKB_GSO_TCP_ECN;
    90  
    91                  if (hdr->gso_size == 0)
    92                          return -EINVAL;
    93          }
    94  
    95          skb_reset_mac_header(skb);
    96  
    97          if (hdr->flags & VIRTIO_NET_HDR_F_NEEDS_CSUM) {
    98                  u32 start = __virtio16_to_cpu(little_endian, 
hdr->csum_start);
    99                  u32 off = __virtio16_to_cpu(little_endian, 
hdr->csum_offset);
   100                  u32 needed = start + max_t(u32, thlen, off + 
sizeof(__sum16));
   101  
   102                  if (hdr->gso_size) {
 > 103                          ret = div64_u64_rem(skb->len, hdr->gso_size, 
 > &remainder);
 > 104                          if (!(ret && (hdr->gso_size > needed) &&
   105                                                  ((remainder > needed) 
|| (remainder == 0)))) {
   106                                  return -EINVAL;
   107                          }
   108                          skb_shinfo(skb)->tx_flags |= SKBFL_SHARED_FRAG;
   109                  }
   110  
   111                  if (!pskb_may_pull(skb, needed))
   112                          return -EINVAL;
   113  
   114                  if (!skb_partial_csum_set(skb, start, off))
   115                          return -EINVAL;
   116  
   117                  nh_min_len = max_t(u32, nh_min_len, 
skb_transport_offset(skb));
   118                  p_off = nh_min_len + thlen;
   119                  if (!pskb_may_pull(skb, p_off))
   120                          return -EINVAL;
   121          } else {
   122                  /* gso packets without NEEDS_CSUM do not set 
transport_offset.
   123                   * probe and drop if does not match one of the above 
types.
   124                   */
   125                  if (gso_type && skb->network_header) {
   126                          struct flow_keys_basic keys;
   127  
   128                          if (!skb->protocol) {
   129                                  __be16 protocol = 
dev_parse_header_protocol(skb);
   130  
   131                                  if (!protocol)
   132                                          virtio_net_hdr_set_proto(skb, 
hdr);
   133                                  else if 
(!virtio_net_hdr_match_proto(protocol, hdr->gso_type))
   134                                          return -EINVAL;
   135                                  else
   136                                          skb->protocol = protocol;
   137                          }
   138  retry:
   139                          if (!skb_flow_dissect_flow_keys_basic(NULL, 
skb, &keys,
   140                                                                NULL, 0, 
0, 0,
   141                                                                0)) {
   142                                  /* UFO does not specify ipv4 or 6: try 
both */
   143                                  if (gso_type & SKB_GSO_UDP &&
   144                                      skb->protocol == htons(ETH_P_IP)) {
   145                                          skb->protocol = 
htons(ETH_P_IPV6);
   146                                          goto retry;
   147                                  }
   148                                  return -EINVAL;
   149                          }
   150  
   151                          p_off = keys.control.thoff + thlen;
   152                          if (!pskb_may_pull(skb, p_off) ||
   153                              keys.basic.ip_proto != ip_proto)
   154                                  return -EINVAL;
   155  
   156                          skb_set_transport_header(skb, 
keys.control.thoff);
   157                  } else if (gso_type) {
   158                          p_off = nh_min_len + thlen;
   159                          if (!pskb_may_pull(skb, p_off))
   160                                  return -EINVAL;
   161                  }
   162          }
   163  
   164          if (hdr->gso_type != VIRTIO_NET_HDR_GSO_NONE) {
   165                  u16 gso_size = __virtio16_to_cpu(little_endian, 
hdr->gso_size);
   166                  unsigned int nh_off = p_off;
   167                  struct skb_shared_info *shinfo = skb_shinfo(skb);
   168  
   169                  switch (gso_type & ~SKB_GSO_TCP_ECN) {
   170                  case SKB_GSO_UDP:
   171                          /* UFO may not include transport header in 
gso_size. */
   172                          nh_off -= thlen;
   173                          break;
   174                  case SKB_GSO_UDP_L4:
   175                          if (!(hdr->flags & VIRTIO_NET_HDR_F_NEEDS_CSUM))
   176                                  return -EINVAL;
   177                          if (skb->csum_offset != offsetof(struct udphdr, 
check))
   178                                  return -EINVAL;
   179                          if (skb->len - p_off > gso_size * 
UDP_MAX_SEGMENTS)
   180                                  return -EINVAL;
   181                          if (gso_type != SKB_GSO_UDP_L4)
   182                                  return -EINVAL;
   183                          break;
   184                  }
   185  
   186                  /* Kernel has a special handling for GSO_BY_FRAGS. */
   187                  if (gso_size == GSO_BY_FRAGS)
   188                          return -EINVAL;
   189  
   190                  /* Too small packets are not really GSO ones. */
   191                  if (skb->len - nh_off > gso_size) {
   192                          shinfo->gso_size = gso_size;
   193                          shinfo->gso_type = gso_type;
   194  
   195                          /* Header must be checked, and gso_segs 
computed. */
   196                          shinfo->gso_type |= SKB_GSO_DODGY;
   197                          shinfo->gso_segs = 0;
   198                  }
   199          }
   200  
   201          return 0;
   202  }
   203  

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

Reply via email to