diff options
author | Omar Polo <op@omarpolo.com> | 2024-07-08 20:18:26 +0000 |
---|---|---|
committer | Omar Polo <op@omarpolo.com> | 2024-07-08 20:18:26 +0000 |
commit | 6c57d2002bb318a9069ae48355ab46ac64a3a7b5 (patch) | |
tree | e0fc9e170447781e1a6e7f689bd2b7d69641ada5 | |
parent | 0206e8c7a235411c6c9c9bda0aa8d03d5d760d9c (diff) |
proxy protocol v1: handle EOF and short reads
-rw-r--r-- | server.c | 17 |
1 files changed, 13 insertions, 4 deletions
@@ -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"); |