[PATCH] linux: Fix aliasing violations and assert address in __check_pf (bug #33927)
Arjun Shankar
arjun@redhat.com
Wed Mar 4 11:36:04 GMT 2026
The Linux implementation of __check_pf retrieves interface data via
make_request, which queries the kernel via netlink. The IFA_ADDRESS
received from the kernel's RTM_NEWADDR netlink message is (a)
type-punned via pointer-casting leading to strict aliasing violations,
and (b) dereferenced assuming that it is non-NULL.
This commit removes the strict-aliasing violations using memcpy, and
adds an assert that the address is indeed non-NULL before dereferencing
it.
Reported-by: Siteshwar Vashisht <svashisht@redhat.com>
---
sysdeps/unix/sysv/linux/check_pf.c | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
diff --git a/sysdeps/unix/sysv/linux/check_pf.c b/sysdeps/unix/sysv/linux/check_pf.c
index b8c7cca1ab..b40ff237aa 100644
--- a/sysdeps/unix/sysv/linux/check_pf.c
+++ b/sysdeps/unix/sysv/linux/check_pf.c
@@ -203,17 +203,24 @@ make_request (int fd, pid_t pid)
out:
if (ifam->ifa_family == AF_INET)
{
- if (*(const in_addr_t *) address
- != htonl (INADDR_LOOPBACK))
+ in_addr_t inaddr;
+ memcpy (&inaddr, address, sizeof (inaddr));
+ if (inaddr != htonl (INADDR_LOOPBACK))
seen_ipv4 = true;
}
else
{
- if (!IN6_IS_ADDR_LOOPBACK (address))
+ struct in6_addr in6addr;
+ memcpy (&in6addr, address, sizeof (in6addr));
+ if (!IN6_IS_ADDR_LOOPBACK (&in6addr))
seen_ipv6 = true;
}
}
+ /* An RTM_NEWADDR message always comes with an address.
+ We de-reference address below. */
+ assert (address != NULL);
+
if (result_len == 0 || result_len == result_cap)
{
result_cap = 2 * result_cap;
@@ -239,7 +246,7 @@ make_request (int fd, pid_t pid)
info->addr[0] = 0;
info->addr[1] = 0;
info->addr[2] = htonl (0xffff);
- info->addr[3] = *(const in_addr_t *) address;
+ memcpy (&info->addr[3], address, sizeof (info->addr[3]));
}
else
memcpy (info->addr, address, sizeof (info->addr));
--
2.52.0
More information about the Libc-alpha
mailing list