aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOmar Polo <op@omarpolo.com>2024-07-08 20:18:26 +0000
committerOmar Polo <op@omarpolo.com>2024-07-08 20:18:26 +0000
commit6c57d2002bb318a9069ae48355ab46ac64a3a7b5 (patch)
treee0fc9e170447781e1a6e7f689bd2b7d69641ada5
parent0206e8c7a235411c6c9c9bda0aa8d03d5d760d9c (diff)
proxy protocol v1: handle EOF and short reads
-rw-r--r--server.c17
1 files changed, 13 insertions, 4 deletions
diff --git a/server.c b/server.c
index f2f5c7b..faa8c29 100644
--- a/server.c
+++ b/server.c
@@ -1301,7 +1301,7 @@ read_cb(struct tls *ctx, void *buf, size_t buflen, void *cb_arg)
struct proxy_protocol_v1 pp1 = {0};
char protostr[1024];
ssize_t ret;
- size_t left, copy, consumed;
+ size_t left, avail, copy, consumed;
int status;
if (!c->proxy_proto) {
@@ -1326,13 +1326,22 @@ read_cb(struct tls *ctx, void *buf, size_t buflen, void *cb_arg)
return copy;
}
- /* buffer layer exists, we expect proxy protocol */
- ret = read(c->fd, c->buf.data + c->buf.len, BUFLAYER_MAX - c->buf.len);
+ avail = sizeof(c->buf.data) - c->buf.len - 1; /* for a NUL */
+ if (avail == 0) {
+ log_warnx("read_cb: overlong proxy protocol v1 header");
+ return -1;
+ }
+
+ ret = read(c->fd, c->buf.data + c->buf.len, avail);
if (ret == -1 && errno == EWOULDBLOCK)
return TLS_WANT_POLLIN;
-
+ if (ret <= 0)
+ return ret;
c->buf.len += ret;
+ if (memmem(c->buf.data, c->buf.len, "\r\n", 2) == NULL)
+ return TLS_WANT_POLLIN;
+
status = proxy_proto_v1_parse(&pp1, c->buf.data, c->buf.len, &consumed);
if (status == -1) {
log_warnx("read_cb: received invalid proxy protocol header");