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.