Armali
Armali

Reputation: 19375

Why does sendto() a Unix domain datagram socket (`socket(PF_FILE, SOCK_DGRAM, 0)`) return EPERM?

On a Linux 2.6.34 ppc system in a multi-process application under certain circumstances, sendto() between two PF_UNIX sockets returns -1 and errno EPERM. The only mention of EPERM in this context which I could find in the manual pages is in UNIX(7):

EPERM The sender passed invalid credentials in the struct ucred.

But this can't apply to sendto(), can it? Unfortunately, I couldn't put together a short, self-contained example to reproduce the problem yet. Here's an strace of the events:

socket(PF_FILE, SOCK_DGRAM, 0)          = 3
bind(3, {sa_family=AF_FILE, path=@"PIO "}, 11) = 0
...
sendto(3, "PIO \0\7\0\20\1\232\1\10\4\1\0\4\20\2\202\30\0\2\0\0", 24, MSG_DONTWAIT, {sa_family=AF_FILE, path=@"PWE7"}, 11) = 24
...
recv(3, "PAD \0#\0\2\3\347", 2008, 0)   = 10
recv(3, "PAD \0#\0\2\3\347", 2008, 0)   = 10
recv(3, "PAD \0#\0\2\3\347", 2008, 0)   = 10
recv(3, "DBUG\0(\0\n\1\250\0\3\0\1\0\1\0\1", 2008, 0) = 18
sendto(3, "PIO \0\3\0\30\1\303\0\3\0\1\0\1\0\1\0\1\20\2\202\34\0\2\0\0\0\2\0\0", 32, MSG_DONTWAIT, {sa_family=AF_FILE, path=@"DBUG"}, 11) = -1 EPERM (Operation not permitted)
recv(3, "PAD \0#\0\2\3\347", 2008, 0)   = 10
recv(3, "PAD \0#\0\2\3\347", 2008, 0)   = 10
recv(3, "PAD \0#\0\2\3\347", 2008, 0)   = 10
...

The process which gets the EPERM receives periodic messages "PAD ..." from one socket before and after it receives from another one a message "DBUG..." to which it shall respond using sendto(). Now, how can it be that this sendto() fails with EPERM, whereas other sendto()s (to other sockets) succeeded before?

Upvotes: 3

Views: 2954

Answers (1)

Gabriel Staples
Gabriel Staples

Reputation: 52687

Update: the OP helped me understand that the below answer does NOT answer his question, since he is asking about UNIX domain sockets, created with socket(PF_FILE, ..., ...), whatever that means :), and I am answering about IP sockets, created with socket(AF_INET, ..., ...).

So, for UNIX domain sockets, this may not be relevant. And, for AF_INET IP domain sockets, see this other Q&A now I just added here instead: How to fix EPERM error when trying to use sendto() with Ethernet socket(AF_INET, ..., ...) (IP output packets) on Linux.

Here is my relevant comment below this question:

@Armali, you are correct. I am mistaken. Thanks for the clarification. I'll ask a new Q&A and move my answer when I get a chance. I was using socket(AF_INET, ..., ...), similar to this example I wrote here, and mistakenly thought you had done the same. I didn't realize you are using socket(PF_FILE, ..., ...). You're right. I don't know anything about that usage.

How to fix EPERM (permissions error; 'E'rror 'PERM'issions) by disabling the firewall

After a ton of study, googling, testing on an embedded Linux board, etc, I've determined it's simply because you have a firewall up blocking your traffic. Do this to disable the firewall, then try again, and the EPERM error will go away:

# Manually disable the firewall
iptables -P INPUT ACCEPT
iptables -P OUTPUT ACCEPT
iptables -P FORWARD ACCEPT
iptables -t filter --flush

Upvotes: 1

Related Questions