(root)/
gcc-13.2.0/
gcc/
testsuite/
gcc.dg/
plugin/
infoleak-net-ethtool-ioctl.c
       1  /* Reduced from infoleak false positive seen on Linux kernel with
       2     net/ethtool/ioctl.c  */
       3  
       4  /* { dg-do compile } */
       5  /* { dg-options "-fanalyzer" } */
       6  /* { dg-require-effective-target analyzer } */
       7  
       8  typedef signed char __s8;
       9  typedef unsigned char __u8;
      10  typedef unsigned int __u32;
      11  typedef __s8 s8;
      12  typedef __u32 u32;
      13  enum { false = 0, true = 1 };
      14  typedef unsigned long __kernel_ulong_t;
      15  typedef __kernel_ulong_t __kernel_size_t;
      16  typedef _Bool bool;
      17  typedef __kernel_size_t size_t;
      18  
      19  void *memset(void *s, int c, size_t n);
      20  
      21  extern bool
      22  check_copy_size(const void *addr, size_t bytes, bool is_source);
      23  extern unsigned long
      24  _copy_from_user(void *, const void *, unsigned long);
      25  extern unsigned long
      26  _copy_to_user(void *, const void *, unsigned long);
      27  
      28  static inline
      29  __attribute__((__always_inline__)) unsigned long
      30  copy_from_user(void *to, const void *from, unsigned long n) {
      31    if (__builtin_expect(!!(check_copy_size(to, n, false)), 1))
      32      n = _copy_from_user(to, from, n);
      33    return n;
      34  }
      35  static inline
      36  __attribute__((__always_inline__)) unsigned long
      37  copy_to_user(void *to, const void *from, unsigned long n) {
      38    if (__builtin_expect(!!(check_copy_size(from, n, true)), 1))
      39      n = _copy_to_user(to, from, n);
      40    return n;
      41  }
      42  enum ethtool_link_mode_bit_indices {
      43    __ETHTOOL_LINK_MODE_MASK_NBITS = 92
      44  };
      45  struct ethtool_link_settings {
      46    __u32 cmd;
      47    /* [...snip...] */
      48    __s8 link_mode_masks_nwords;
      49    /* [...snip...] */
      50  };
      51  
      52  struct ethtool_link_ksettings {
      53    struct ethtool_link_settings base;
      54    u32 lanes;
      55  };
      56  
      57  int ethtool_get_link_ksettings(void *useraddr) {
      58    int err = 0;
      59    struct ethtool_link_ksettings link_ksettings;
      60  
      61    if (copy_from_user(&link_ksettings.base, useraddr,
      62                       sizeof(link_ksettings.base)))
      63      return -14;
      64  
      65    if ((((__ETHTOOL_LINK_MODE_MASK_NBITS) + (32) - 1) / (32)) !=
      66        link_ksettings.base.link_mode_masks_nwords) {
      67  
      68      memset(&link_ksettings, 0, sizeof(link_ksettings));
      69      link_ksettings.base.cmd = 0x0000004c;
      70  
      71      link_ksettings.base.link_mode_masks_nwords =
      72          -((s8)(((__ETHTOOL_LINK_MODE_MASK_NBITS) + (32) - 1) / (32)));
      73  
      74      if (copy_to_user(useraddr, &link_ksettings.base,
      75                       sizeof(link_ksettings.base)))
      76        return -14;
      77  
      78      return 0;
      79    }
      80  
      81    return 0;
      82  }