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 { union epoll_ref {
struct { struct {
int32_t proto:8, int32_t proto:8,
s:24; #define SOCKET_REF_BITS 24
#define SOCKET_MAX (1 << SOCKET_REF_BITS)
s:SOCKET_REF_BITS;
union { union {
union tcp_epoll_ref tcp; union tcp_epoll_ref tcp;
union udp_epoll_ref udp; 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) if (s < 0)
s = socket(af, SOCK_STREAM | SOCK_NONBLOCK, IPPROTO_TCP); s = socket(af, SOCK_STREAM | SOCK_NONBLOCK, IPPROTO_TCP);
if (s > SOCKET_MAX) {
close(s);
return -EIO;
}
if (s < 0) if (s < 0)
return -errno; return -errno;
@ -2982,6 +2987,12 @@ static int tcp_sock_refill(void *arg)
break; break;
} }
*p4 = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK, IPPROTO_TCP); *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); 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, *p6 = socket(AF_INET6, SOCK_STREAM | SOCK_NONBLOCK,
IPPROTO_TCP); IPPROTO_TCP);
if (*p6 > SOCKET_MAX) {
close(*p6);
*p6 = -1;
return -EIO;
}
tcp_sock_set_bufsize(a->c, *p6); 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; const struct sockaddr *sa;
socklen_t sl; socklen_t sl;
if (sock_conn < 0)
return -errno;
if (sock_conn > SOCKET_MAX) {
close(sock_conn);
return -EIO;
}
conn->b = sock_conn; conn->b = sock_conn;
if (s < 0) 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, s = socket(v6 ? AF_INET6 : AF_INET, SOCK_DGRAM | SOCK_NONBLOCK,
IPPROTO_UDP); IPPROTO_UDP);
if (s > SOCKET_MAX) {
close(s);
return -EIO;
}
if (s < 0) if (s < 0)
return s; return s;
ref.r.s = s; ref.r.s = s;
if (v6) { 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); fd = socket(af, SOCK_STREAM | SOCK_NONBLOCK, proto);
else else
fd = socket(af, SOCK_DGRAM | SOCK_NONBLOCK, proto); fd = socket(af, SOCK_DGRAM | SOCK_NONBLOCK, proto);
if (fd < 0) { if (fd < 0) {
perror("L4 socket"); perror("L4 socket");
return -1; return -1;
} }
if (fd > SOCKET_MAX) {
close(fd);
return -EIO;
}
ref.r.s = fd; ref.r.s = fd;
if (af == AF_INET) { if (af == AF_INET) {