[PATCH] linux: Fix aliasing violations and assert address in __check_pf (bug #33927)
Adhemerval Zanella Netto
adhemerval.zanella@linaro.org
Tue Mar 10 20:27:32 GMT 2026
On 04/03/26 08:36, Arjun Shankar wrote:
> 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>
LGTM, thanks.
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
> ---
> 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));
More information about the Libc-alpha
mailing list