From 375c65a9c2f5fef9796672078769104074530ec1 Mon Sep 17 00:00:00 2001 From: Stefan Puiu Date: Fri, 29 May 2020 10:11:48 +0300 Subject: [PATCH] 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 --- man2/connect.2 | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/man2/connect.2 b/man2/connect.2 index 41296cf4e..d051d1c28 100644 --- a/man2/connect.2 +++ b/man2/connect.2 @@ -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)