mailing list of musl libc
 help / color / mirror / code / Atom feed
* getaddrinfo/AI_ADDRCONFIG with ipv6 disabled
@ 2019-12-05  2:44 Bob Richmond
  2021-04-30  0:13 ` [musl] " Rich Felker
  0 siblings, 1 reply; 9+ messages in thread
From: Bob Richmond @ 2019-12-05  2:44 UTC (permalink / raw)
  To: musl

[-- Attachment #1: Type: text/plain, Size: 1054 bytes --]

connect() to the IPv6 loopback address can fail with EACCES on Linux if 
IPv6 is disabled on the lo interface, and causes getaddrinfo to fail 
without returning IPv4 addresses. It should be treated as if IPv6 is 
disabled.

echo 1 >/proc/sys/net/ipv6/conf/lo/disable_ipv6

struct addrinfo hints, *res = NULL;
hints.ai_family = PF_UNSPEC;
hints.ai_flags = AI_ADDRCONFIG;
getaddrinfo("192.168.1.1", "80", &hints, &res);

strace:
======start=======
socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC, IPPROTO_UDP) = 14
connect(14, {sa_family=AF_INET, sin_port=htons(65535), 
sin_addr=inet_addr("127.0.0.1")}, 16) = 0
close(14)                         = 0 

socket(AF_INET6, SOCK_DGRAM|SOCK_CLOEXEC, IPPROTO_UDP) = 14 

connect(14, {sa_family=AF_INET6, sin6_port=htons(65535), 
inet_pton(AF_INET6, "::1", &sin6_addr), sin6_flowinfo=htonl(0), 
sin6_scope_id=0}, 28) = -1 EACCES (Permission denied)
close(14)                         = 0
writev(2, [{iov_base="[warn] getaddrinfo: Permission denied\n", 
iov_len=38}, {iov_base=NULL, iov_len=0}], 2) = 38
======end=========

[-- Attachment #2: musl-getaddrinfo-ipv6-eacces.patch --]
[-- Type: text/x-patch, Size: 304 bytes --]

--- musl-1.1.24/src/network/getaddrinfo.c	2019-10-13 14:58:27.000000000 -0700
+++ musl-1.1.24/src/network/getaddrinfo.c	2019-12-04 14:52:11.003784091 -0800
@@ -76,6 +76,7 @@
 			case EHOSTUNREACH:
 			case ENETDOWN:
 			case ENETUNREACH:
+			case EACCES:
 				break;
 			default:
 				return EAI_SYSTEM;

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [musl] getaddrinfo/AI_ADDRCONFIG with ipv6 disabled
  2019-12-05  2:44 getaddrinfo/AI_ADDRCONFIG with ipv6 disabled Bob Richmond
@ 2021-04-30  0:13 ` Rich Felker
  2021-04-30 12:38   ` Rich Felker
  0 siblings, 1 reply; 9+ messages in thread
From: Rich Felker @ 2021-04-30  0:13 UTC (permalink / raw)
  To: Bob Richmond; +Cc: musl

On Wed, Dec 04, 2019 at 06:44:29PM -0800, Bob Richmond wrote:
> connect() to the IPv6 loopback address can fail with EACCES on Linux
> if IPv6 is disabled on the lo interface, and causes getaddrinfo to
> fail without returning IPv4 addresses. It should be treated as if
> IPv6 is disabled.
> 
> echo 1 >/proc/sys/net/ipv6/conf/lo/disable_ipv6
> 
> struct addrinfo hints, *res = NULL;
> hints.ai_family = PF_UNSPEC;
> hints.ai_flags = AI_ADDRCONFIG;
> getaddrinfo("192.168.1.1", "80", &hints, &res);
> 
> strace:
> ======start=======
> socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC, IPPROTO_UDP) = 14
> connect(14, {sa_family=AF_INET, sin_port=htons(65535),
> sin_addr=inet_addr("127.0.0.1")}, 16) = 0
> close(14)                         = 0
> 
> socket(AF_INET6, SOCK_DGRAM|SOCK_CLOEXEC, IPPROTO_UDP) = 14
> 
> connect(14, {sa_family=AF_INET6, sin6_port=htons(65535),
> inet_pton(AF_INET6, "::1", &sin6_addr), sin6_flowinfo=htonl(0),
> sin6_scope_id=0}, 28) = -1 EACCES (Permission denied)
> close(14)                         = 0
> writev(2, [{iov_base="[warn] getaddrinfo: Permission denied\n",
> iov_len=38}, {iov_base=NULL, iov_len=0}], 2) = 38
> ======end=========

> --- musl-1.1.24/src/network/getaddrinfo.c	2019-10-13 14:58:27.000000000 -0700
> +++ musl-1.1.24/src/network/getaddrinfo.c	2019-12-04 14:52:11.003784091 -0800
> @@ -76,6 +76,7 @@
>  			case EHOSTUNREACH:
>  			case ENETDOWN:
>  			case ENETUNREACH:
> +			case EACCES:
>  				break;
>  			default:
>  				return EAI_SYSTEM;

This patch was overlooked at the time, and another user just stopped
by #musl to ask why it wasn't applied. I'm going to go ahead and apply
it now. Sorry for the long delay!

Rich

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [musl] getaddrinfo/AI_ADDRCONFIG with ipv6 disabled
  2021-04-30  0:13 ` [musl] " Rich Felker
@ 2021-04-30 12:38   ` Rich Felker
  2021-04-30 16:40     ` Bastian Bittorf
  2021-04-30 16:59     ` Jeffrey Walton
  0 siblings, 2 replies; 9+ messages in thread
From: Rich Felker @ 2021-04-30 12:38 UTC (permalink / raw)
  To: Bob Richmond; +Cc: musl

On Thu, Apr 29, 2021 at 08:13:03PM -0400, Rich Felker wrote:
> On Wed, Dec 04, 2019 at 06:44:29PM -0800, Bob Richmond wrote:
> > connect() to the IPv6 loopback address can fail with EACCES on Linux
> > if IPv6 is disabled on the lo interface, and causes getaddrinfo to
> > fail without returning IPv4 addresses. It should be treated as if
> > IPv6 is disabled.
> > 
> > echo 1 >/proc/sys/net/ipv6/conf/lo/disable_ipv6
> > 
> > struct addrinfo hints, *res = NULL;
> > hints.ai_family = PF_UNSPEC;
> > hints.ai_flags = AI_ADDRCONFIG;
> > getaddrinfo("192.168.1.1", "80", &hints, &res);
> > 
> > strace:
> > ======start=======
> > socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC, IPPROTO_UDP) = 14
> > connect(14, {sa_family=AF_INET, sin_port=htons(65535),
> > sin_addr=inet_addr("127.0.0.1")}, 16) = 0
> > close(14)                         = 0
> > 
> > socket(AF_INET6, SOCK_DGRAM|SOCK_CLOEXEC, IPPROTO_UDP) = 14
> > 
> > connect(14, {sa_family=AF_INET6, sin6_port=htons(65535),
> > inet_pton(AF_INET6, "::1", &sin6_addr), sin6_flowinfo=htonl(0),
> > sin6_scope_id=0}, 28) = -1 EACCES (Permission denied)
> > close(14)                         = 0
> > writev(2, [{iov_base="[warn] getaddrinfo: Permission denied\n",
> > iov_len=38}, {iov_base=NULL, iov_len=0}], 2) = 38
> > ======end=========
> 
> > --- musl-1.1.24/src/network/getaddrinfo.c	2019-10-13 14:58:27.000000000 -0700
> > +++ musl-1.1.24/src/network/getaddrinfo.c	2019-12-04 14:52:11.003784091 -0800
> > @@ -76,6 +76,7 @@
> >  			case EHOSTUNREACH:
> >  			case ENETDOWN:
> >  			case ENETUNREACH:
> > +			case EACCES:
> >  				break;
> >  			default:
> >  				return EAI_SYSTEM;
> 
> This patch was overlooked at the time, and another user just stopped
> by #musl to ask why it wasn't applied. I'm going to go ahead and apply
> it now. Sorry for the long delay!

It's been raised that this is NOT a result of

    echo 1 >/proc/sys/net/ipv6/conf/lo/disable_ipv6

but rather appears to be fib6 policy setup by OpenWRT for some reason,
whereby the kernel (net/ipv6/fib6_rules.c: fib6_rule_action)
synthesizes error codes for routing policy reasons. This is probably
wrong for the kernel to do -- especially their re-appropriation of
EINVAL for FR_ACT_BLACKHOLE when POSIX already specifies it for

    "The address_len argument is not a valid length for the address
    family; or invalid address family in the sockaddr structure."

So in light of this mess, the patch may be correct, despite the
problem being misattributed, but it should probably also handle the
EINVAL case. Also it's not 100% clear whether we should interpret this
as "no IPv6" or ignore it as an access control policy rather than
reflection of IPv6 existing. If there are any other ways the kernel
can return EACCES or EINVAL here, we would not want to misinterpret
that in a way that breaks IPv6.

Someone should probably also ping OpenWRT about why they're using this
arcane mechanism to block IPv6 to localhost.

Rich

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [musl] getaddrinfo/AI_ADDRCONFIG with ipv6 disabled
  2021-04-30 12:38   ` Rich Felker
@ 2021-04-30 16:40     ` Bastian Bittorf
  2021-04-30 16:52       ` Rich Felker
  2021-04-30 16:59     ` Jeffrey Walton
  1 sibling, 1 reply; 9+ messages in thread
From: Bastian Bittorf @ 2021-04-30 16:40 UTC (permalink / raw)
  To: musl

On Fri, Apr 30, 2021 at 08:38:04AM -0400, Rich Felker wrote:
> Someone should probably also ping OpenWRT about why they're using this
> arcane mechanism to block IPv6 to localhost.

at least I can see:
https://git.openwrt.org/?p=openwrt/svn-archive/archive.git;a=blob;f=target/linux/generic/patches-3.19/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch;h=f32458df30ad466d4e3ac8224cbec1bd074b43ec;hb=35d90ba52069c96afd1a74600b91499e5feed0e0

I was last refreshed on Tue Mar 30 22:01:27 2021 +0100
and says:

"RFC6204 L-14 requires rejecting traffic from invalid addresses with
 ICMPv6 Destination Unreachable, Code 5 (Source address failed ingress/
 egress policy) on the LAN side, so add an appropriate rule for that."

But that is just guessing...

bye, Bastian

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [musl] getaddrinfo/AI_ADDRCONFIG with ipv6 disabled
  2021-04-30 16:40     ` Bastian Bittorf
@ 2021-04-30 16:52       ` Rich Felker
  2021-04-30 17:59         ` Julian Squires
  0 siblings, 1 reply; 9+ messages in thread
From: Rich Felker @ 2021-04-30 16:52 UTC (permalink / raw)
  To: Bastian Bittorf; +Cc: musl

On Fri, Apr 30, 2021 at 04:40:33PM +0000, Bastian Bittorf wrote:
> On Fri, Apr 30, 2021 at 08:38:04AM -0400, Rich Felker wrote:
> > Someone should probably also ping OpenWRT about why they're using this
> > arcane mechanism to block IPv6 to localhost.
> 
> at least I can see:
> https://git.openwrt.org/?p=openwrt/svn-archive/archive.git;a=blob;f=target/linux/generic/patches-3.19/670-ipv6-allow-rejecting-with-source-address-failed-policy.patch;h=f32458df30ad466d4e3ac8224cbec1bd074b43ec;hb=35d90ba52069c96afd1a74600b91499e5feed0e0
> 
> I was last refreshed on Tue Mar 30 22:01:27 2021 +0100
> and says:
> 
> "RFC6204 L-14 requires rejecting traffic from invalid addresses with
>  ICMPv6 Destination Unreachable, Code 5 (Source address failed ingress/
>  egress policy) on the LAN side, so add an appropriate rule for that."
> 
> But that is just guessing...

Presumably that would be for traffic originating from another host
OpenWRT is forwarding for (blocking it from spoofing ::1 on the wire?)
not for traffic originating on the OpenWRT box itself (where ::1
should work). I'm worried that if we just "fix" this issue on the musl
side, OpenWRT is just wrongly going to conclude there's no IPv6
coonnectivity rather than that they have a configuration error
breaking it..

Rich

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [musl] getaddrinfo/AI_ADDRCONFIG with ipv6 disabled
  2021-04-30 12:38   ` Rich Felker
  2021-04-30 16:40     ` Bastian Bittorf
@ 2021-04-30 16:59     ` Jeffrey Walton
  2021-04-30 18:49       ` Markus Wichmann
  1 sibling, 1 reply; 9+ messages in thread
From: Jeffrey Walton @ 2021-04-30 16:59 UTC (permalink / raw)
  To: musl; +Cc: Bob Richmond

On Fri, Apr 30, 2021 at 8:38 AM Rich Felker <dalias@libc.org> wrote:
> ....
> It's been raised that this is NOT a result of
>
>     echo 1 >/proc/sys/net/ipv6/conf/lo/disable_ipv6
>
> but rather appears to be fib6 policy setup by OpenWRT for some reason,
> whereby the kernel (net/ipv6/fib6_rules.c: fib6_rule_action)
> synthesizes error codes for routing policy reasons. This is probably
> wrong for the kernel to do -- especially their re-appropriation of
> EINVAL for FR_ACT_BLACKHOLE when POSIX already specifies it for
>
>     "The address_len argument is not a valid length for the address
>     family; or invalid address family in the sockaddr structure."
>
> So in light of this mess, the patch may be correct, despite the
> problem being misattributed, but it should probably also handle the
> EINVAL case. Also it's not 100% clear whether we should interpret this
> as "no IPv6" or ignore it as an access control policy rather than
> reflection of IPv6 existing. If there are any other ways the kernel
> can return EACCES or EINVAL here, we would not want to misinterpret
> that in a way that breaks IPv6.
>
> Someone should probably also ping OpenWRT about why they're using this
> arcane mechanism to block IPv6 to localhost.

The kernel has been doing that stupid thing for ages. They have no
interest in fixing it. (I brought it up on one of the kernel mailing
lists).

It gets worse with components like SELinux. They hijack error codes
there, too. You can waste hours trying to track down an EACCESS on a
web server only to find out the kernel hijacked the return code in
SELinux.

God forbid they actually provide a selinux_errno to check for SELinux errors...

Jeff

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [musl] getaddrinfo/AI_ADDRCONFIG with ipv6 disabled
  2021-04-30 16:52       ` Rich Felker
@ 2021-04-30 17:59         ` Julian Squires
  0 siblings, 0 replies; 9+ messages in thread
From: Julian Squires @ 2021-04-30 17:59 UTC (permalink / raw)
  To: Rich Felker; +Cc: musl

Rich Felker <dalias@libc.org> writes:
> So in light of this mess, the patch may be correct, despite the
> problem being misattributed, but it should probably also handle the
> EINVAL case. Also it's not 100% clear whether we should interpret this
> as "no IPv6" or ignore it as an access control policy rather than
> reflection of IPv6 existing. If there are any other ways the kernel
> can return EACCES or EINVAL here, we would not want to misinterpret
> that in a way that breaks IPv6.

I've sent an updated patch to the list.  I did submit a change to
OpenWrt to not create these rules on devices where IPv6 is disabled:

  https://patchwork.ozlabs.org/project/openwrt/patch/20210430143037.6763-1-julian@cipht.net/

but it seems to me that the patch to musl still makes sense, in as much
as these return codes from Linux make any sense at all.
<#secure method=pgpmime mode=sign>

--
Julian Squires

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [musl] getaddrinfo/AI_ADDRCONFIG with ipv6 disabled
  2021-04-30 16:59     ` Jeffrey Walton
@ 2021-04-30 18:49       ` Markus Wichmann
  2021-04-30 19:50         ` Rich Felker
  0 siblings, 1 reply; 9+ messages in thread
From: Markus Wichmann @ 2021-04-30 18:49 UTC (permalink / raw)
  To: musl

On Fri, Apr 30, 2021 at 12:59:39PM -0400, Jeffrey Walton wrote:
> God forbid they actually provide a selinux_errno to check for SELinux errors...
>
> Jeff

Well, that would be difficult. Although the concept of "nicer" errors
has been floated in the past, and having some kind of parametrization
for errno would be helpful (e.g. if ENOENT is returned, actually saying
which file could not be found would be helpful. Because it's not always
obvious). But right now, errno is the only error handling mechanism
established in the ABI, and it is transported by having the system call
return a value between -1 and -4096 (though I'm not sure if that lower
bound is general or just AMD64). Having a second errno would require
either establishing a new system call to read it out, or modifying the
ABI to allow for the information to be transported. There are many
hurdles in the way of the latter (can't use return value, can't use
registers, can only use memory on an opt-in basis, but then you can also
just add another system call directly), so it's going to be the former.

Then the question arrises whether the abstraction is even correct.
Technically, SELinux is just a plug-in security module, and a given
Linux kernel may have many of those. Shall each get their own errno?
Where does it end?

So yeah, it's not as simple as"just add another variable".

Ciao,
Markus

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [musl] getaddrinfo/AI_ADDRCONFIG with ipv6 disabled
  2021-04-30 18:49       ` Markus Wichmann
@ 2021-04-30 19:50         ` Rich Felker
  0 siblings, 0 replies; 9+ messages in thread
From: Rich Felker @ 2021-04-30 19:50 UTC (permalink / raw)
  To: Markus Wichmann; +Cc: musl

On Fri, Apr 30, 2021 at 08:49:17PM +0200, Markus Wichmann wrote:
> On Fri, Apr 30, 2021 at 12:59:39PM -0400, Jeffrey Walton wrote:
> > God forbid they actually provide a selinux_errno to check for SELinux errors...
> >
> > Jeff
> 
> Well, that would be difficult. Although the concept of "nicer" errors
> has been floated in the past, and having some kind of parametrization
> for errno would be helpful (e.g. if ENOENT is returned, actually saying
> which file could not be found would be helpful. Because it's not always
> obvious). But right now, errno is the only error handling mechanism
> established in the ABI, and it is transported by having the system call
> return a value between -1 and -4096 (though I'm not sure if that lower
> bound is general or just AMD64). Having a second errno would require
> either establishing a new system call to read it out, or modifying the
> ABI to allow for the information to be transported. There are many
> hurdles in the way of the latter (can't use return value, can't use
> registers, can only use memory on an opt-in basis, but then you can also
> just add another system call directly), so it's going to be the former.
> 
> Then the question arrises whether the abstraction is even correct.
> Technically, SELinux is just a plug-in security module, and a given
> Linux kernel may have many of those. Shall each get their own errno?
> Where does it end?
> 
> So yeah, it's not as simple as"just add another variable".

Yes, the underlying issue is just SELinux, LSMs, firewall/routing
policy, seccomp, etc. producing wrong error codes (or letting the user
configure it to produce wrong error codes), rather than hard-coding
the cause. For example in the case here, nobody needs to know EACCES.
The important piece of information to the application is that the
connection is not routeable, and this is ENETUNREACH or EHOSTUNREACH.
Routing is always a matter of some sort of policy, so "this was
blocked by fib6 [vs iptables vs just not having a route, etc.]" is not
meaningful to the application.

If there were a secondary way to give more detailed error information,
it might be nice to give it, but in the absence of that, the right
solution is just "don't replace well-specified general error codes the
application knows to handle with overly specific ones it can't (and
that might even mean something else to it, in the case of EINVAL).

Rich

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2021-04-30 19:50 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-12-05  2:44 getaddrinfo/AI_ADDRCONFIG with ipv6 disabled Bob Richmond
2021-04-30  0:13 ` [musl] " Rich Felker
2021-04-30 12:38   ` Rich Felker
2021-04-30 16:40     ` Bastian Bittorf
2021-04-30 16:52       ` Rich Felker
2021-04-30 17:59         ` Julian Squires
2021-04-30 16:59     ` Jeffrey Walton
2021-04-30 18:49       ` Markus Wichmann
2021-04-30 19:50         ` Rich Felker

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/musl/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).