tcp, udp, util: Enforce 24-bit limit on socket numbers

This should never happen, but there are no formal guarantees: ensure
socket numbers are below SOCKET_MAX.

Signed-off-by: Stefano Brivio <sbrivio@redhat.com>
This commit is contained in:
Stefano Brivio 2022-03-15 23:17:44 +01:00
parent 66a95e331e
commit 3eb19cfd8a
5 changed files with 42 additions and 1 deletions

View file

@ -45,7 +45,9 @@ union epoll_ref;
union epoll_ref {
struct {
int32_t proto:8,
s:24;
#define SOCKET_REF_BITS 24
#define SOCKET_MAX (1 << SOCKET_REF_BITS)
s:SOCKET_REF_BITS;
union {
union tcp_epoll_ref tcp;
union udp_epoll_ref udp;

17
tcp.c
View file

@ -1971,6 +1971,11 @@ static int tcp_conn_new_sock(struct ctx *c, sa_family_t af)
if (s < 0)
s = socket(af, SOCK_STREAM | SOCK_NONBLOCK, IPPROTO_TCP);
if (s > SOCKET_MAX) {
close(s);
return -EIO;
}
if (s < 0)
return -errno;
@ -2982,6 +2987,12 @@ static int tcp_sock_refill(void *arg)
break;
}
*p4 = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, IPPROTO_TCP);
if (*p4 > SOCKET_MAX) {
close(*p4);
*p4 = -1;
return -EIO;
}
tcp_sock_set_bufsize(a->c, *p4);
}
@ -2991,6 +3002,12 @@ static int tcp_sock_refill(void *arg)
}
*p6 = socket(AF_INET6, SOCK_STREAM | SOCK_NONBLOCK,
IPPROTO_TCP);
if (*p6 > SOCKET_MAX) {
close(*p6);
*p6 = -1;
return -EIO;
}
tcp_sock_set_bufsize(a->c, *p6);
}

View file

@ -418,6 +418,14 @@ static int tcp_splice_connect(struct ctx *c, struct tcp_splice_conn *conn,
const struct sockaddr *sa;
socklen_t sl;
if (sock_conn < 0)
return -errno;
if (sock_conn > SOCKET_MAX) {
close(sock_conn);
return -EIO;
}
conn->b = sock_conn;
if (s < 0)

7
udp.c
View file

@ -443,8 +443,15 @@ int udp_splice_connect(struct ctx *c, int v6, int bound_sock,
s = socket(v6 ? AF_INET6 : AF_INET, SOCK_DGRAM | SOCK_NONBLOCK,
IPPROTO_UDP);
if (s > SOCKET_MAX) {
close(s);
return -EIO;
}
if (s < 0)
return s;
ref.r.s = s;
if (v6) {

7
util.c
View file

@ -235,10 +235,17 @@ int sock_l4(struct ctx *c, int af, uint8_t proto, uint16_t port,
fd = socket(af, SOCK_STREAM | SOCK_NONBLOCK, proto);
else
fd = socket(af, SOCK_DGRAM | SOCK_NONBLOCK, proto);
if (fd < 0) {
perror("L4 socket");
return -1;
}
if (fd > SOCKET_MAX) {
close(fd);
return -EIO;
}
ref.r.s = fd;
if (af == AF_INET) {