Commit d5a9000d authored by Deomid Ryabkov's avatar Deomid Ryabkov Committed by Cesanta Bot

Harden MQTT parser some more

PUBLISHED_FROM=5e7fcc7bf145aa8e1045e8d627b1c0731bb4341b
parent f6201845
...@@ -9956,19 +9956,31 @@ MG_INTERNAL int parse_mqtt(struct mbuf *io, struct mg_mqtt_message *mm) { ...@@ -9956,19 +9956,31 @@ MG_INTERNAL int parse_mqtt(struct mbuf *io, struct mg_mqtt_message *mm) {
switch (cmd) { switch (cmd) {
case MG_MQTT_CMD_CONNECT: { case MG_MQTT_CMD_CONNECT: {
p = scanto(p, &mm->protocol_name); p = scanto(p, &mm->protocol_name);
if (p > end - 4) return -2;
mm->protocol_version = *(uint8_t *) p++; mm->protocol_version = *(uint8_t *) p++;
mm->connect_flags = *(uint8_t *) p++; mm->connect_flags = *(uint8_t *) p++;
mm->keep_alive_timer = getu16(p); mm->keep_alive_timer = getu16(p);
p += 2; p += 2;
if (p < end) p = scanto(p, &mm->client_id); if (p >= end) return -2;
if (p < end && (mm->connect_flags & MG_MQTT_HAS_WILL)) p = scanto(p, &mm->client_id);
if (p > end) return -2;
if (mm->connect_flags & MG_MQTT_HAS_WILL) {
if (p >= end) return -2;
p = scanto(p, &mm->will_topic); p = scanto(p, &mm->will_topic);
if (p < end && (mm->connect_flags & MG_MQTT_HAS_WILL)) }
if (mm->connect_flags & MG_MQTT_HAS_WILL) {
if (p >= end) return -2;
p = scanto(p, &mm->will_message); p = scanto(p, &mm->will_message);
if (p < end && (mm->connect_flags & MG_MQTT_HAS_USER_NAME)) }
if (mm->connect_flags & MG_MQTT_HAS_USER_NAME) {
if (p >= end) return -2;
p = scanto(p, &mm->user_name); p = scanto(p, &mm->user_name);
if (p < end && (mm->connect_flags & MG_MQTT_HAS_PASSWORD)) }
if (mm->connect_flags & MG_MQTT_HAS_PASSWORD) {
if (p >= end) return -2;
p = scanto(p, &mm->password); p = scanto(p, &mm->password);
}
if (p != end) return -2;
LOG(LL_DEBUG, LOG(LL_DEBUG,
("%d %2x %d proto [%.*s] client_id [%.*s] will_topic [%.*s] " ("%d %2x %d proto [%.*s] client_id [%.*s] will_topic [%.*s] "
...@@ -9982,6 +9994,7 @@ MG_INTERNAL int parse_mqtt(struct mbuf *io, struct mg_mqtt_message *mm) { ...@@ -9982,6 +9994,7 @@ MG_INTERNAL int parse_mqtt(struct mbuf *io, struct mg_mqtt_message *mm) {
break; break;
} }
case MG_MQTT_CMD_CONNACK: case MG_MQTT_CMD_CONNACK:
if (end - p < 2) return -2;
mm->connack_ret_code = p[1]; mm->connack_ret_code = p[1];
break; break;
case MG_MQTT_CMD_PUBACK: case MG_MQTT_CMD_PUBACK:
...@@ -9993,7 +10006,9 @@ MG_INTERNAL int parse_mqtt(struct mbuf *io, struct mg_mqtt_message *mm) { ...@@ -9993,7 +10006,9 @@ MG_INTERNAL int parse_mqtt(struct mbuf *io, struct mg_mqtt_message *mm) {
break; break;
case MG_MQTT_CMD_PUBLISH: { case MG_MQTT_CMD_PUBLISH: {
p = scanto(p, &mm->topic); p = scanto(p, &mm->topic);
if (p > end) return -2;
if (mm->qos > 0) { if (mm->qos > 0) {
if (end - p < 2) return -2;
mm->message_id = getu16(p); mm->message_id = getu16(p);
p += 2; p += 2;
} }
...@@ -10002,6 +10017,7 @@ MG_INTERNAL int parse_mqtt(struct mbuf *io, struct mg_mqtt_message *mm) { ...@@ -10002,6 +10017,7 @@ MG_INTERNAL int parse_mqtt(struct mbuf *io, struct mg_mqtt_message *mm) {
break; break;
} }
case MG_MQTT_CMD_SUBSCRIBE: case MG_MQTT_CMD_SUBSCRIBE:
if (end - p < 2) return -2;
mm->message_id = getu16(p); mm->message_id = getu16(p);
p += 2; p += 2;
/* /*
...@@ -10036,7 +10052,12 @@ static void mqtt_handler(struct mg_connection *nc, int ev, ...@@ -10036,7 +10052,12 @@ static void mqtt_handler(struct mg_connection *nc, int ev,
/* There can be multiple messages in the buffer, process them all. */ /* There can be multiple messages in the buffer, process them all. */
while (1) { while (1) {
int len = parse_mqtt(io, &mm); int len = parse_mqtt(io, &mm);
if (len == -1) break; /* not fully buffered */ if (len < 0) {
if (len == -1) break; /* not fully buffered */
/* Protocol error. */
nc->flags |= MG_F_CLOSE_IMMEDIATELY;
break;
}
nc->handler(nc, MG_MQTT_EVENT_BASE + mm.cmd, &mm MG_UD_ARG(user_data)); nc->handler(nc, MG_MQTT_EVENT_BASE + mm.cmd, &mm MG_UD_ARG(user_data));
mbuf_remove(io, len); mbuf_remove(io, len);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment