diff options
author | Andrei Karas <akaras@inbox.ru> | 2018-11-13 19:01:00 +0300 |
---|---|---|
committer | Andrei Karas <akaras@inbox.ru> | 2018-11-15 01:40:31 +0300 |
commit | dcf07d8a47221b92942f5c62d3d64ab9f86b8f8c (patch) | |
tree | f31c5447339420d259176e0489fdc0dda55d7f12 /src/common/socket.c | |
parent | e35402b608ace44f80928591bad388a0d5765184 (diff) | |
download | hercules-dcf07d8a47221b92942f5c62d3d64ab9f86b8f8c.tar.gz hercules-dcf07d8a47221b92942f5c62d3d64ab9f86b8f8c.tar.bz2 hercules-dcf07d8a47221b92942f5c62d3d64ab9f86b8f8c.tar.xz hercules-dcf07d8a47221b92942f5c62d3d64ab9f86b8f8c.zip |
Add packet validation for RFIFOSKIP.
Diffstat (limited to 'src/common/socket.c')
-rw-r--r-- | src/common/socket.c | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/src/common/socket.c b/src/common/socket.c index a0096c1da..f9ee16bf9 100644 --- a/src/common/socket.c +++ b/src/common/socket.c @@ -811,7 +811,36 @@ static int rfifoskip(int fd, size_t len) if (s->rdata_size < s->rdata_pos + len) { ShowError("RFIFOSKIP: skipped past end of read buffer! Adjusting from %"PRIuS" to %"PRIuS" (session #%d)\n", len, RFIFOREST(fd), fd); + Assert_report(0); len = RFIFOREST(fd); + } else { + const size_t lenRest = RFIFOREST(fd); + if (s->flag.validate == 1 && len == lenRest) { + if (lenRest >= 2) { + const uint cmd = (uint)RFIFOW(fd, 0); + if (cmd < MIN_PACKET_DB || cmd > MAX_PACKET_DB) { + ShowError("Skip wrong packet id: 0x%04X\n", cmd); + Assert_report(0); + } else { + int packet_len = packets->db[cmd]; + if (packet_len == -1) { + if (lenRest < 4) { + ShowError("Skip packet with size smaller than 4\n"); + Assert_report(0); + } else { + packet_len = RFIFOW(fd, 2); + if (packet_len != lenRest) { + ShowError("Skip packet 0x%04X with dynamic size %"PRIuS", but must be size %d\n", cmd, lenRest, packet_len); + Assert_report(0); + } + } + } else if (packet_len != lenRest) { + ShowError("Skip packet 0x%04X with size %"PRIuS", but must be size %d\n", cmd, lenRest, packet_len); + Assert_report(0); + } + } + } + } } s->rdata_pos = s->rdata_pos + len; |