Home > Enterprise >  Errno set by socket() is undocumented in the manpage
Errno set by socket() is undocumented in the manpage

Time:09-17

The manpage of socket(3p) documents the signature to this function and a basic introduction on how to use it. The error section of this document lists a few errno values with explanations on why the error occurs. Unfortunately, I got an undocumented error reading EPERM with the numerical number 1 indicating Operation not permitted. The undocumented errno was initially discovered under the ArchLinux environment with glibc-2.33 and clang-12.0.1. I hope the following proof-of-concept(PoC) could be reproduced in other Linux environments:

#include <errno.h>
#include <sys/socket.h>
#include <netinet/ip.h>

int main() {
    socket(PF_INET, SOCK_RAW, IPPROTO_TCP);
    return errno;
}

The following command may help reproduce, where the PoC code stores in file raw-socket-poc.c:

$ clang -O0 -g raw-socket-poc.c -o raw-socket-poc
$ ./raw-socket-poc; errno $?
EPERM 1 Operation not permitted

Additional observations show that changing IPPROTO_TCP to IPPROTO_UDP helps nothing. However, by replacing IPROTO_TCP to the suggested 0, the program ends up with a documented error EPROTONOSUPPORT 93 Protocol not supported. Further experiments noticed that running the original PoC as root yold no error. Unfortunately, the undocumented error occurred if the PoC ran as an unprivileged user with the CAP_NET_RAW capability. The capability promotion for the PoC associated with # setcap CAP_NET_RAW= eip ./raw-socket-poc and a double-checked with $ getcap ./raw-socket-poc where ./raw-socket-poc cap_net_raw=eip showed.

With limited information, conclusions are hard to make on whether the lack of documentation is intended or a by-design product. So we may appreciate it if there are explanations on how things work with manpage and raw socket-related capabilities.

CodePudding user response:

If you look at man 2 socket, at the bottom of the "ERRORS" section. you'll see that it mentions that other errors can be generated.

ERRORS
       EACCES Permission to create a socket of the specified type and/or  pro‐
              tocol is denied.

       EAFNOSUPPORT
              The  implementation  does not support the specified address fam‐
              ily.

       EINVAL Unknown protocol, or protocol family not available.

       EINVAL Invalid flags in type.

       EMFILE Process file table overflow.

       ENFILE The system limit on the total number  of  open  files  has  been
              reached.

       ENOBUFS or ENOMEM
              Insufficient  memory is available.  The socket cannot be created
              until sufficient resources are freed.

       EPROTONOSUPPORT
              The protocol type or the specified  protocol  is  not  supported
              within this domain.

       Other errors may be generated by the underlying protocol modules.

If we then check man 7 raw:

SYNOPSIS

       #include <sys/socket.h>
       #include <netinet/in.h>
       raw_socket = socket(AF_INET, SOCK_RAW, int protocol);

...

ERRORS

       EACCES User tried to send to a broadcast address without having
              the broadcast flag set on the socket.

       EFAULT An invalid memory address was supplied.

       EINVAL Invalid argument.

       EMSGSIZE
              Packet too big.  Either Path MTU Discovery is enabled (the
              IP_MTU_DISCOVER socket flag) or the packet size exceeds
              the maximum allowed IPv4 packet size of 64 kB.

       EOPNOTSUPP
              Invalid flag has been passed to a socket call (like
              MSG_OOB).

       EPERM  The user doesn't have permission to open raw sockets.
              Only processes with an effective user ID of 0 or the
              CAP_NET_RAW attribute may do that.

       EPROTO An ICMP error has arrived reporting a parameter problem.

We see that EPERM can be generated.

  • Related