-
Notifications
You must be signed in to change notification settings - Fork 13.3k
WiFiClientSecure invalid read buffer #3002
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
This is a very valid issue. The pointer will not be invalid (axTLS uses same buffer for reading and writing, and the buffer is not re-allocated), but if you do a write after an incomplete read, then the next read operation will happily return data from the buffer which now contains encrypted transmitted data. AxTLS uses one buffer for reading and writing, so is essentially half-duplex. You must read out all data at the application layer before writing data into axTLS, otherwise you get this issue. This doesn't happen with e.g. HTTP and SMTP due to half-duplex nature of these protocols. This does however happen with MQTT. Of all the options listed, option 2 looks like it has highest chances of being implemented, even though I wouldn't like to deviate too much from the original axTLS API to make future updates easier. |
I've implemented the solutions in options 2 and 3 in #3019. |
I am having trouble with MQTT over TLS and I suspect this is the issue, I'm using 2.3.0 stable and lmroy's pubsubclient. My esp is connected to the broker on port 8883 and subscribed to a couple of topics (a command channel for example) and is also publishing data at intervals on other topics. Im finding the subscriptions are not receiving published messages from the broker if the esp itself is actively publishing, it basically ignores commands sent to it, and eventually crashes some time later with exception 9 and others, I assume due to corrupt buffers. If I switch to non-tls port 1883, I have no such issues, no crashes and the subscriptions always hear the published messages. I appear to have about 23k of heap free under tls. What would be the shortest path to making this work properly over TLS? Can I deploy the #3019 patch over my 2.3.0? Or wait for a new version? or simply do the mqtt client.loop before the publish? (Im not sure that will solve the issue fully). I appreciate your expertise and suggestions. |
You should definitely try the #3019 and knolleary/pubsubclient#251 patches. After you set that up, tell us how it went ;) |
We're experiencing the same problem when using Blynk (https://github.com/blynkkk/blynk-library) with WiFiClientSecure. Blynk is also a Full-Duplex protocol. |
Workaround implemented in #4024. |
Basic Infos
Hardware
Hardware: ESP-8266 in a Sonoff Switch
Core Version: 2.3.0
Description
WiFiClientSecure may read from an invalid buffer, causing any number of undefined behaviours.
To compute available(), the internal SSLContext in WiFiClientSecure calls axTLS's ssl_read(SSL* ssl, uint8_t** in_data), which gives access to a temporary internal buffer through in_data (See notes which indicate to use in_data before performing any other ssl_* operations). SSLContext then proceeds to save a reference to the internal buffer in its _read_ptr member field, as a cache for subsequent calls to SSLContext.read().
However, unless the read() calls are performed immediately after calling available(), the reference saved in _read_ptr may not be valid anymore. In particular, if the context is used for writing in between, the reference will be obsolete and calls to WiFiClientSecure.read() will return garbage (or access invalid memory).
The problem is aggravated by the fact that many functions call available(), including connected().
In particular, I'm using a modified PubSubClient to implement a MQTT client (modified to use an internal WiFiClientSecure as its underlying channel). Using a simple loop as shown below halts the program, since by the time the program actually reads the buffer, the MQTT packet's "message length" is an arbitrary number (typically larger than the real message length, which is very small) and the readPacket() function tries to read beyond what the broker has sent, blocking forever (or until the socket times out).
If the order of the internal operations is reversed, everything works fine.
Some possible solutions:
Settings in IDE
Module: Generic ESP8266 Module
Flash Size: 1MB
CPU Frequency: 80Mhz
Flash Mode: DIO
Flash Frequency: 40Mhz
Upload Using: SERIAL
Reset Method: ck
The text was updated successfully, but these errors were encountered: