https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84863

            Bug ID: 84863
           Summary: false-positive -Warray-bounds warning with
                    -fsanitize-coverage=object-size
           Product: gcc
           Version: 8.0.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: sanitizer
          Assignee: unassigned at gcc dot gnu.org
          Reporter: arnd at linaro dot org
                CC: dodji at gcc dot gnu.org, dvyukov at gcc dot gnu.org,
                    jakub at gcc dot gnu.org, kcc at gcc dot gnu.org, marxin at 
gcc dot gnu.org
  Target Milestone: ---

Created attachment 43655
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=43655&action=edit
linux/net/xfrm/xfrm_output.c, preprocessed, not reduced.

Among the linux kernel build warnings I see from enabling sanitizers
(CONFIG_UBSAN_SANITIZE_ALL), this is one that seems interesting and not yet
reported:

In file included from /git/arm-soc/include/linux/kernel.h:10,
                 from /git/arm-soc/include/linux/list.h:9,
                 from /git/arm-soc/include/linux/module.h:9,
                 from /git/arm-soc/net/xfrm/xfrm_output.c:13:
/git/arm-soc/net/xfrm/xfrm_output.c: In function 'xfrm_output_resume':
/git/arm-soc/include/linux/compiler.h:251:20: error: array subscript 4 is above
array bounds of 'struct nf_hook_entries *[3]' [-Werror=array-bounds]
   __read_once_size(&(x), __u.__c, sizeof(x));  \
                    ^~~~
/git/arm-soc/include/linux/compiler.h:257:22: note: in expansion of macro
'__READ_ONCE'
 #define READ_ONCE(x) __READ_ONCE(x, 1)
                      ^~~~~~~~~~~
/git/arm-soc/include/linux/rcupdate.h:351:48: note: in expansion of macro
'READ_ONCE'
  typeof(*p) *________p1 = (typeof(*p) *__force)READ_ONCE(p); \
                                                ^~~~~~~~~
/git/arm-soc/include/linux/rcupdate.h:488:2: note: in expansion of macro
'__rcu_dereference_check'
  __rcu_dereference_check((p), (c) || rcu_read_lock_held(), __rcu)
  ^~~~~~~~~~~~~~~~~~~~~~~
/git/arm-soc/include/linux/rcupdate.h:546:28: note: in expansion of macro
'rcu_dereference_check'
 #define rcu_dereference(p) rcu_dereference_check(p, 0)
                            ^~~~~~~~~~~~~~~~~~~~~
/git/arm-soc/include/linux/netfilter.h:219:15: note: in expansion of macro
'rcu_dereference'
   hook_head = rcu_dereference(net->nf.hooks_arp[hook]);
               ^~~~~~~~~~~~~~~

The original function looks like

static inline int nf_hook(u_int8_t pf, unsigned int hook, struct net *net,
                          struct sock *sk, struct sk_buff *skb,
                          struct net_device *indev, struct net_device *outdev,
                          int (*okfn)(struct net *, struct sock *, struct
sk_buff *))
{
        struct nf_hook_entries *hook_head = NULL;
        int ret = 1;

        rcu_read_lock();
        switch (pf) {
        case NFPROTO_IPV4:
                hook_head = rcu_dereference(net->nf.hooks_ipv4[hook]);
                break;
        case NFPROTO_IPV6:
                hook_head = rcu_dereference(net->nf.hooks_ipv6[hook]);
                break;
        case NFPROTO_ARP:
#ifdef CONFIG_NETFILTER_FAMILY_ARP
                hook_head = rcu_dereference(net->nf.hooks_arp[hook]);
#endif
                break;
        case NFPROTO_BRIDGE:
#ifdef CONFIG_NETFILTER_FAMILY_BRIDGE
                hook_head = rcu_dereference(net->nf.hooks_bridge[hook]);
#endif
                break;
#if IS_ENABLED(CONFIG_DECNET)
        case NFPROTO_DECNET:
                hook_head = rcu_dereference(net->nf.hooks_decnet[hook]);
                break;
#endif
        default:
                WARN_ON_ONCE(1);
                break;
        }

where the net->nf.hooks_* fields all have different sizes. The function is
called with constant arguments for 'pf' and 'hook', and for this caller, the
latter is out of range for the net->nf.hooks_arp[] array, but in a line that
is never reached. Reproduced with all versions that support the object-size
sanitizer (gcc-5 through 8).

With the attached preprocessed file, reproduce with

$ arm-linux-gnueabi-gcc-8.0.1 -Wall -O2 -c net/xfrm/xfrm_output.i -Werror  
-fsanitize=object-size  -fno-strict-aliasing

The warning also shows up with an x86 compiler, but that causes other problems.
I can produce a reduced version that works on x86 if needed.

Reply via email to