Message ID | 20250107165509.3008505-1-gal@nvidia.com (mailing list archive) |
---|---|
State | Changes Requested |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | [net-next] net: Silence false field-spanning write warning in ip_tunnel_info_opts_set() memcpy | expand |
On January 7, 2025 8:55:09 AM PST, Gal Pressman <gal@nvidia.com> wrote: >When metadata_dst struct is allocated (using metadata_dst_alloc()), it >reserves room for options at the end of the struct. > >Similar to [1], change the memcpy() to unsafe_memcpy() as it is >guaranteed that enough room (md_size bytes) was allocated and the >field-spanning write is intentional. Why not just add an "options" flex array to struct ip_tunnel_info? E.g.: struct ip_tunnel_info { struct ip_tunnel_key key; struct ip_tunnel_encap encap; #ifdef CONFIG_DST_CACHE struct dst_cache dst_cache; #endif u8 options_len; u8 mode; u8 options[] __counted_by(options_len); }; > >This resolves the following warning: > memcpy: detected field-spanning write (size 8) of single field "_Generic(info, const struct ip_tunnel_info * : ((const void *)((info) + 1)), struct ip_tunnel_info * : ((void *)((info) + 1)) )" at include/net/ip_tunnels.h:662 (size 0) Then you can drop this macro and just use: info->options Looks like you'd need to do it for all the types in struct metadata_dst, but at least you could stop hiding it from the compiler. :) -Kees
On 08/01/2025 1:28, Kees Cook wrote: > > > On January 7, 2025 8:55:09 AM PST, Gal Pressman <gal@nvidia.com> wrote: >> When metadata_dst struct is allocated (using metadata_dst_alloc()), it >> reserves room for options at the end of the struct. >> >> Similar to [1], change the memcpy() to unsafe_memcpy() as it is >> guaranteed that enough room (md_size bytes) was allocated and the >> field-spanning write is intentional. > > Why not just add an "options" flex array to struct ip_tunnel_info? > > E.g.: > > struct ip_tunnel_info { > struct ip_tunnel_key key; > struct ip_tunnel_encap encap; > #ifdef CONFIG_DST_CACHE > struct dst_cache dst_cache; > #endif > u8 options_len; > u8 mode; > u8 options[] __counted_by(options_len); > }; > >> >> This resolves the following warning: >> memcpy: detected field-spanning write (size 8) of single field "_Generic(info, const struct ip_tunnel_info * : ((const void *)((info) + 1)), struct ip_tunnel_info * : ((void *)((info) + 1)) )" at include/net/ip_tunnels.h:662 (size 0) > > Then you can drop this macro and just use: info->options > > Looks like you'd need to do it for all the types in struct metadata_dst, but at least you could stop hiding it from the compiler. :) > > -Kees > > Thanks for the review Kees, I'll take a look into that.
diff --git a/include/net/ip_tunnels.h b/include/net/ip_tunnels.h index 1aa31bdb2b31..d5e163eba234 100644 --- a/include/net/ip_tunnels.h +++ b/include/net/ip_tunnels.h @@ -659,7 +659,10 @@ static inline void ip_tunnel_info_opts_set(struct ip_tunnel_info *info, { info->options_len = len; if (len > 0) { - memcpy(ip_tunnel_info_opts(info), from, len); + unsafe_memcpy(ip_tunnel_info_opts(info), from, len, + /* metadata_dst_alloc() reserves room (md_size bytes) + * for options right after the ip_tunnel_info struct. + */); ip_tunnel_flags_or(info->key.tun_flags, info->key.tun_flags, flags); }