diff options
author | Stefano Brivio <sbrivio@redhat.com> | 2022-03-15 23:17:44 +0100 |
---|---|---|
committer | Stefano Brivio <sbrivio@redhat.com> | 2022-03-29 15:35:38 +0200 |
commit | 3eb19cfd8a7c03920aeecae6692048429288af88 (patch) | |
tree | 88ffb6c69fab2da82a9d9910da1c57d34804d739 | |
parent | 66a95e331ec930e72bc06c54b283ea88b30ecbaa (diff) | |
download | passt-3eb19cfd8a7c03920aeecae6692048429288af88.tar passt-3eb19cfd8a7c03920aeecae6692048429288af88.tar.gz passt-3eb19cfd8a7c03920aeecae6692048429288af88.tar.bz2 passt-3eb19cfd8a7c03920aeecae6692048429288af88.tar.lz passt-3eb19cfd8a7c03920aeecae6692048429288af88.tar.xz passt-3eb19cfd8a7c03920aeecae6692048429288af88.tar.zst passt-3eb19cfd8a7c03920aeecae6692048429288af88.zip |
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>
-rw-r--r-- | passt.h | 4 | ||||
-rw-r--r-- | tcp.c | 17 | ||||
-rw-r--r-- | tcp_splice.c | 8 | ||||
-rw-r--r-- | udp.c | 7 | ||||
-rw-r--r-- | util.c | 7 |
5 files changed, 42 insertions, 1 deletions
@@ -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; @@ -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); } diff --git a/tcp_splice.c b/tcp_splice.c index cb8df7b..d374785 100644 --- a/tcp_splice.c +++ b/tcp_splice.c @@ -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) @@ -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) { @@ -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) { |