diff options
author | Stefano Brivio <sbrivio@redhat.com> | 2022-05-19 13:07:33 +0200 |
---|---|---|
committer | Stefano Brivio <sbrivio@redhat.com> | 2022-05-19 16:27:20 +0200 |
commit | c318ffcb4c932752cd1f48bf5d1b0268f58895bd (patch) | |
tree | 30f28814818a2ef35a424379749732b5f32bef32 | |
parent | 3d4c2a44a69bba90f3ca70ba998b92ce892bbcd8 (diff) | |
download | passt-c318ffcb4c932752cd1f48bf5d1b0268f58895bd.tar passt-c318ffcb4c932752cd1f48bf5d1b0268f58895bd.tar.gz passt-c318ffcb4c932752cd1f48bf5d1b0268f58895bd.tar.bz2 passt-c318ffcb4c932752cd1f48bf5d1b0268f58895bd.tar.lz passt-c318ffcb4c932752cd1f48bf5d1b0268f58895bd.tar.xz passt-c318ffcb4c932752cd1f48bf5d1b0268f58895bd.tar.zst passt-c318ffcb4c932752cd1f48bf5d1b0268f58895bd.zip |
udp: Ignore bogus -Wstringop-overread for write() from gcc 12.1
With current OpenSUSE Tumbleweed on aarch64 (gcc-12-1.3.aarch64) and
on x86_64 (gcc-12-1.4.x86_64), but curiously not on armv7hl
(gcc-12-1.3.armv7hl), gcc warns about using the _pointer_ to the
802.3 header to write the whole frame to the tap descriptor:
reading between 62 and 4294967357 bytes from a region of size 14
which is bogus:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103483
Probably declaring udp_sock_fill_data_v{4,6}() as noinline would
"fix" this, but that's on the data path, so I'd rather not. Use
a gcc pragma instead.
Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
-rw-r--r-- | udp.c | 4 | ||||
-rw-r--r-- | util.h | 23 |
2 files changed, 27 insertions, 0 deletions
@@ -714,8 +714,10 @@ static void udp_sock_fill_data_v4(const struct ctx *c, int n, b->uh.len = htons(udp4_l2_mh_sock[n].msg_len + sizeof(b->uh)); if (c->mode == MODE_PASTA) { + PRAGMA_STRINGOP_OVERREAD_IGNORE if (write(c->fd_tap, &b->eh, sizeof(b->eh) + ip_len) < 0) debug("tap write: %s", strerror(errno)); + PRAGMA_STRINGOP_OVERREAD_IGNORE_POP pcap((char *)&b->eh, sizeof(b->eh) + ip_len); return; @@ -813,8 +815,10 @@ static void udp_sock_fill_data_v6(const struct ctx *c, int n, b->ip6h.hop_limit = 255; if (c->mode == MODE_PASTA) { + PRAGMA_STRINGOP_OVERREAD_IGNORE if (write(c->fd_tap, &b->eh, sizeof(b->eh) + ip_len) < 0) debug("tap write: %s", strerror(errno)); + PRAGMA_STRINGOP_OVERREAD_IGNORE_POP pcap((char *)&b->eh, sizeof(b->eh) + ip_len); return; @@ -102,6 +102,29 @@ enum { (void *)(arg)); \ } while (0) + +#ifdef __has_warning +# if __has_warning("-Wstringop-overread") +# define PRAGMA_STRINGOP_OVERREAD_IGNORE \ + _Pragma("GCC diagnostic ignored \"-Wstringop-overread\"") +# define PRAGMA_STRINGOP_OVERREAD_IGNORE_POP \ + _Pragma("GCC diagnostic pop") +# else +# define PRAGMA_STRINGOP_OVERREAD_IGNORE +# define PRAGMA_STRINGOP_OVERREAD_IGNORE_POP +# endif +#else +# if defined(__GNUC__) && __GNUC__ >= 11 +# define PRAGMA_STRINGOP_OVERREAD_IGNORE \ + _Pragma("GCC diagnostic ignored \"-Wstringop-overread\"") +# define PRAGMA_STRINGOP_OVERREAD_IGNORE_POP \ + _Pragma("GCC diagnostic pop") +# else +# define PRAGMA_STRINGOP_OVERREAD_IGNORE +# define PRAGMA_STRINGOP_OVERREAD_IGNORE_POP +# endif +#endif + #if __BYTE_ORDER == __BIG_ENDIAN #define L2_BUF_ETH_IP4_INIT \ { \ |