summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrei Karas <akaras@inbox.ru>2018-11-13 19:01:00 +0300
committerAndrei Karas <akaras@inbox.ru>2018-11-15 01:40:31 +0300
commitdcf07d8a47221b92942f5c62d3d64ab9f86b8f8c (patch)
treef31c5447339420d259176e0489fdc0dda55d7f12
parente35402b608ace44f80928591bad388a0d5765184 (diff)
downloadhercules-dcf07d8a47221b92942f5c62d3d64ab9f86b8f8c.tar.gz
hercules-dcf07d8a47221b92942f5c62d3d64ab9f86b8f8c.tar.bz2
hercules-dcf07d8a47221b92942f5c62d3d64ab9f86b8f8c.tar.xz
hercules-dcf07d8a47221b92942f5c62d3d64ab9f86b8f8c.zip
Add packet validation for RFIFOSKIP.
-rw-r--r--src/common/socket.c29
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;