aboutgitcodebugslistschat
path: root/udp.c
diff options
context:
space:
mode:
authorStefano Brivio <sbrivio@redhat.com>2022-09-28 20:45:55 +0200
committerStefano Brivio <sbrivio@redhat.com>2022-09-29 12:23:10 +0200
commit5290b6f13e493b3fc814b4dc7fac2b5d7c252245 (patch)
tree1f00c7a831e93ed5c201e69b6b6c357d19a6087d /udp.c
parent505a33e9f9d9d766e39fd9c54c6cb2136ae99ecb (diff)
downloadpasst-5290b6f13e493b3fc814b4dc7fac2b5d7c252245.tar
passt-5290b6f13e493b3fc814b4dc7fac2b5d7c252245.tar.gz
passt-5290b6f13e493b3fc814b4dc7fac2b5d7c252245.tar.bz2
passt-5290b6f13e493b3fc814b4dc7fac2b5d7c252245.tar.lz
passt-5290b6f13e493b3fc814b4dc7fac2b5d7c252245.tar.xz
passt-5290b6f13e493b3fc814b4dc7fac2b5d7c252245.tar.zst
passt-5290b6f13e493b3fc814b4dc7fac2b5d7c252245.zip
udp: Replace pragma to ignore bogus stringop-overread warning with workaround
Commit c318ffcb4c93 ("udp: Ignore bogus -Wstringop-overread for write() from gcc 12.1") uses a gcc pragma to ignore a bogus warning, which started appearing on gcc 12.1 (aarch64 and x86_64) due to: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103483 ...but gcc 12.2 has the same issue. Not just that: if LTO is enabled, the pragma itself is ignored (this wasn't the case with gcc 12.1), because of: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80922 Drop the pragma, and assign a frame (in the networking sense) pointer from the offset of the Ethernet header in the buffer, then pass it to write() and pcap(), so that gcc doesn't obsess anymore with the fact that an Ethernet header is 14 bytes and we're sending more than that. Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
Diffstat (limited to 'udp.c')
-rw-r--r--udp.c26
1 files changed, 18 insertions, 8 deletions
diff --git a/udp.c b/udp.c
index bd3dc72..d1be622 100644
--- a/udp.c
+++ b/udp.c
@@ -704,11 +704,20 @@ 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)
+ /* If we pass &b->eh directly to write(), starting from
+ * gcc 12.1, at least on aarch64 and x86_64, we get a bogus
+ * stringop-overread warning, due to:
+ * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=103483
+ *
+ * but we can't disable it with a pragma, because it will be
+ * ignored if LTO is enabled:
+ * https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80922
+ */
+ void *frame = (char *)b + offsetof(struct udp4_l2_buf_t, eh);
+
+ if (write(c->fd_tap, frame, 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);
+ pcap(frame, sizeof(b->eh) + ip_len);
return;
}
@@ -805,11 +814,12 @@ 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)
+ /* See udp_sock_fill_data_v4() for the reason behind 'frame' */
+ void *frame = (char *)b + offsetof(struct udp6_l2_buf_t, eh);
+
+ if (write(c->fd_tap, frame, 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);
+ pcap(frame, sizeof(b->eh) + ip_len);
return;
}