connect.2: Can return EACCES because of SELinux

Recently I had to troubleshoot a problem where a connect() call
was returning EACCES:

17648 socket(AF_INET, SOCK_STREAM, IPPROTO_IP) = 37
17648 connect(37, {sa_family=AF_INET, sin_port=htons(8081),
sin_addr=inet_addr("10.12.1.201")}, 16) = -1 EACCES (Permission
denied)

I've traced this to SELinux policy denying the connection. This is
on a Fedora 23 VM:

$ cat /etc/redhat-release
Fedora release 23 (Twenty Three)
$ uname -a
Linux mako-fedora-01 4.8.13-100.fc23.x86_64 #1 SMP Fri Dec 9 14:51:40
UTC 2016 x86_64 x86_64 x86_64 GNU/Linux

The manpage says this can happen when connecting to a broadcast
address, or when a local firewall rule blocks the connection.
However, the address above is unicast, and using 'wget' from
another account to access the URL works fine.

The context is that we're building an OS image, and this involves
downloading RPMs through a proxy. The proxy (polipo) is labelled
by SELinux, and I guess there is some sort of policy that says
"proxy can only connect to HTTP ports". When trying to connect to
a server listening on a port that is not labeled as an HTTP server
port, I guess SELinux steps in. With 'setenforce 0', the build
works fine. In the kernel sources I see connect() calls
security_socket_connect() (see
https://elixir.bootlin.com/linux/latest/source/net/socket.c#L1855),
which calls whatever security hooks are registered. I see the
SELinux hook getting registered at
https://elixir.bootlin.com/linux/latest/source/security/selinux/hooks.c#L7047,
and setting a perf probe on the call proves that the
selinux_socket_connect function gets called (while
tcp_v4_connect() is not).

Signed-off-by: Michael Kerrisk <mtk.manpages@gmail.com>
This commit is contained in:
Stefan Puiu 2020-05-29 10:11:48 +03:00 committed by Michael Kerrisk
parent 94e316bfea
commit 375c65a9c2
1 changed files with 9 additions and 1 deletions

View File

@ -155,6 +155,13 @@ in the path prefix.
The user tried to connect to a broadcast address without having the socket
broadcast flag enabled or the connection request failed because of a local
firewall rule.
.B EACCES
can also be returned if a SELinux policy denied a connection (for
example, if there is a policy saying that an HTTP proxy can only
connect to ports associated with HTTP servers, and the proxy tries to
connect to a different port).
.TP
.B EADDRINUSE
Local address is already in use.
@ -297,4 +304,5 @@ is shown in
.BR getsockname (2),
.BR listen (2),
.BR socket (2),
.BR path_resolution (7)
.BR path_resolution (7),
.BR selinux (8)