Follow @Openwall on Twitter for new release announcements and other news
[<prev] [<thread-prev] [day] [month] [year] [list]
Message-ID: <20250726015637.GJ1827@brightrain.aerifal.cx>
Date: Fri, 25 Jul 2025 21:56:37 -0400
From: Rich Felker <dalias@...c.org>
To: Thorsten Glaser <tg@...bsd.de>
Cc: musl@...ts.openwall.com
Subject: Re: Bug in IN6_IS_ADDR_V4COMPAT macro for addresses ending in
 .1

On Sat, Jul 26, 2025 at 02:53:19AM +0200, Thorsten Glaser wrote:
> On Fri, 25 Jul 2025, Rich Felker wrote:
> 
> >>  +         ((uint32_t *) (a))[2] == 0 && ((uint32_t *) (a))[3] > 1)
> >>
> >> Untested, and I’ve not yet had enough coffee, so DWIM ☻
> >
> >This is not valid, You can't do order comparisons on the uint32_t
> >units because they're byte order dependent.
> 
> Oh, right.
> 
> >But I suspect the actual intent is not >1 but !=0.
> 
> No, it is exactly “NOT IN (0, 1)”.

Yeah, I realized this later. Oops.

> Basically, :: (IPv6 any) and ::1 (IPv6 localhost) need to be excluded
> from the sets of IPv6 addresses that begin with all-zero before an
> embedded IPv4 address (except 0.0.0.0 and 0.0.0.1), and optionally
> a :FFFF: before *that*, depending on use case (apparently not here).

V4MAPPED is a different thing than V4COMPAT. The latter is actually
useless and so probably nobody has cared about this macro being wrong
because it only comes up in tests, not in any actual usage.

> +         ((uint32_t *) (a))[2] == 0 && ntohl((uint32_t *) (a))[3] > 1)
> 
> Maybe this?

That's basically what glibc does. but we could also just do the simple
legible logic: top bits all zero && !IN6_IS_ADDR_UNSPECIFIED(a) &&
!IN6_IS_ADDR_LOOPBACK(a). All the redundant top-bits-zero checks
collapse out in CSE anyway.

Rich

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.