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:
parent
66a95e331e
commit
3eb19cfd8a
5 changed files with 42 additions and 1 deletions
4
passt.h
4
passt.h
|
@ -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
17
tcp.c
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
7
udp.c
|
@ -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
7
util.c
|
@ -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) {
|
||||||
|
|
Loading…
Reference in a new issue