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>
This commit is contained in:
Stefano Brivio 2022-05-19 13:07:33 +02:00
parent 3d4c2a44a6
commit c318ffcb4c
2 changed files with 27 additions and 0 deletions

4
udp.c
View file

@ -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;

23
util.h
View file

@ -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 \
{ \