aboutgitcodebugslistschat
diff options
context:
space:
mode:
authorStefano Brivio <sbrivio@redhat.com>2022-03-15 23:17:44 +0100
committerStefano Brivio <sbrivio@redhat.com>2022-03-29 15:35:38 +0200
commit3eb19cfd8a7c03920aeecae6692048429288af88 (patch)
tree88ffb6c69fab2da82a9d9910da1c57d34804d739
parent66a95e331ec930e72bc06c54b283ea88b30ecbaa (diff)
downloadpasst-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.h4
-rw-r--r--tcp.c17
-rw-r--r--tcp_splice.c8
-rw-r--r--udp.c7
-rw-r--r--util.c7
5 files changed, 42 insertions, 1 deletions
diff --git a/passt.h b/passt.h
index 8344fca..3a62b15 100644
--- a/passt.h
+++ b/passt.h
@@ -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;
diff --git a/tcp.c b/tcp.c
index 1eeb627..fcd9a04 100644
--- a/tcp.c
+++ b/tcp.c
@@ -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)
diff --git a/udp.c b/udp.c
index ad8a775..e22f3ac 100644
--- a/udp.c
+++ b/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,
IPPROTO_UDP);
+
+ if (s > SOCKET_MAX) {
+ close(s);
+ return -EIO;
+ }
+
if (s < 0)
return s;
+
ref.r.s = s;
if (v6) {
diff --git a/util.c b/util.c
index 2d8952a..ff7d97b 100644
--- a/util.c
+++ b/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);
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) {