diff --git a/examples/mqttnet.c b/examples/mqttnet.c index 19450be5..5abb22cf 100644 --- a/examples/mqttnet.c +++ b/examples/mqttnet.c @@ -172,7 +172,13 @@ static int NetRead(void *context, byte* buf, int buf_len, rc = MQTT_CODE_ERROR_NETWORK; } else { - rc = bytes; + /* Bound the byte count to buf_len before narrowing to int: this + * guards against a callback reporting more than was requested and + * keeps the word32->int cast within range */ + if (bytes > (word32)buf_len) { + bytes = (word32)buf_len; + } + rc = (int)bytes; } return rc; @@ -1851,6 +1857,11 @@ static int NetRead_ex(void *context, byte* buf, int buf_len, } else { rc = bytes; + /* Never report more than the caller requested; guards against a + * read callback that returns more bytes than buf_len */ + if (rc > buf_len) { + rc = buf_len; + } } return rc; diff --git a/src/mqtt_packet.c b/src/mqtt_packet.c index 2f78344a..b5f37a01 100644 --- a/src/mqtt_packet.c +++ b/src/mqtt_packet.c @@ -4042,6 +4042,11 @@ int MqttPacket_Read(MqttClient *client, byte* rx_buf, int rx_buf_len, if (rc <= 0) { return MqttPacket_HandleNetError(client, rc); } + /* Socket read must not return more than requested */ + if (rc > remain_read) { + return MqttPacket_HandleNetError(client, + MQTT_TRACE_ERROR(MQTT_CODE_ERROR_NETWORK)); + } remain_read = rc; } break; diff --git a/src/mqtt_socket.c b/src/mqtt_socket.c index e6866203..de65fc0a 100644 --- a/src/mqtt_socket.c +++ b/src/mqtt_socket.c @@ -356,6 +356,11 @@ int MqttSocket_Read(MqttClient *client, byte* buf, int buf_len, int timeout_ms) /* return length read and reset position */ rc = client->read.pos; client->read.pos = 0; + /* Never report more than the caller requested; guards against a + * read callback that returns more bytes than buf_len */ + if (rc > buf_len) { + rc = buf_len; + } } return rc;