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.