OpenMQTTGateway
OpenMQTTGateway copied to clipboard
Wrong base topic if gateway_name is changed
Describe the bug
Using home/OpenMQTTGateway/commands/MQTTtoSYS/config topic :
If mqtt_topic and gateway_name are changed at the same time, then only gateway_name is set,
Resulting in base topic <gateway_name>/, instead of <mqtt_topic>/<gateway_name>/.
To Reproduce
Each time on a fresh install with base topic set to home/OpenMQTTGateway/:
Publish {"mqtt_topic":"bt/"} on home/OpenMQTTGateway/commands/MQTTtoSYS/config
Base topic becomes bt/OpenMQTTGateway/ -> OK
Publish {"gateway_name":"OMG"} on home/OpenMQTTGateway/commands/MQTTtoSYS/config
Base topic becomes home/OMG/ -> OK
Publish {"mqtt_topic":"bt/","gateway_name":"OMG"} on home/OpenMQTTGateway/commands/MQTTtoSYS/config
Base topic becomes OMG/ -> KO
Expected behavior
When publishing {"mqtt_topic":"bt/","gateway_name":"OMG"} on home/OpenMQTTGateway/commands/MQTTtoSYS/config
Base topic should becomes bt/OMG/
Environment (please complete the following information): OpenMQTTGateway version used V0.9.13, esp32-lolin32lite-ble on ESP32
Checks: Code responsible of this feature is really straightforward PR #1053: https://github.com/1technophile/OpenMQTTGateway/blob/v0.9.13/main/main.ino#L2070-L2080
I don't understand why only 1 parameter works at the time.
Maybe stopProcessing() is required before saveMqttConfig() and startProcessing() after client.disconnect()...
Thanks for pointing that out, any idea @h2zero ?
I just re-tested with v0.9.14 to be sure.
Actually I was wrong.
I did not test in this order and can tel that each time gateway_name is set, base topic becomes <gateway_name>/.
So (Each time on a fresh install with base topic set to home/OpenMQTTGateway/):
- Publish
{"mqtt_topic":"bt/"}onhome/OpenMQTTGateway/commands/MQTTtoSYS/configBase topic becomesbt/OpenMQTTGateway/-> OK
Debug log:
N: [ MQTT->OMG ]: {"mqtt_topic":"bt/"}
{
"mqtt_server": "192.168.11.3",
"mqtt_port": "1883",
"mqtt_user": "",
"mqtt_pass": "",
"mqtt_topic": "bt/",
"gateway_name": "OpenMQTTGateway",
"mqtt_broker_secure": false,
"mqtt_broker_cert": "",
"mqtt_ss_index": 0,
"ota_server_cert": ""
}
- Publish
{"gateway_name":"OMG"}onhome/OpenMQTTGateway/commands/MQTTtoSYS/configBase topic becomesOMG/-> KO
Debug log:
N: [ MQTT->OMG ]: {"gateway_name":"OMG"}
{
"mqtt_server": "192.168.11.3",
"mqtt_port": "1883",
"mqtt_user": "",
"mqtt_pass": "",
"mqtt_topic": "",
"gateway_name": "OMG",
"mqtt_broker_secure": false,
"mqtt_broker_cert": "",
"mqtt_ss_index": 0,
"ota_server_cert": ""
}
- Publish
{"mqtt_topic":"bt/","gateway_name":"OMG"}onhome/OpenMQTTGateway/commands/MQTTtoSYS/configBase topic becomesOMG/-> KO
Debug log:
N: [ MQTT->OMG ]: {"mqtt_topic":"bt/","gateway_name":"OMG"}
{
"mqtt_server": "192.168.11.3",
"mqtt_port": "1883",
"mqtt_user": "",
"mqtt_pass": "",
"mqtt_topic": "",
"gateway_name": "OMG",
"mqtt_broker_secure": false,
"mqtt_broker_cert": "",
"mqtt_ss_index": 0,
"ota_server_cert": ""
}
Owwww got it !
gateway_name char* is statically declared with a size of parameters_size here:
https://github.com/1technophile/OpenMQTTGateway/blob/c04c62916fceb5dbb7d834b035d353af178d7492/main/main.ino#L171
But strncpy uses a max length of parameters_size * 2 to copy gateway_name here:
https://github.com/1technophile/OpenMQTTGateway/blob/c04c62916fceb5dbb7d834b035d353af178d7492/main/main.ino#L2075
As gateway_name is declared next to mqtt_topic, I supposed that mqtt_topic was overwritten by strncpy (as it fills the end of dest char* with \0).
So I tested with a 80 char long gateway_name and as I suspected this happened:
N: [ MQTT->OMG ]: {"gateway_name":"01234567890123456789012345678901234567890123456789012345678901234567890123456789","mqtt_topic":"bt/"}
{
"mqtt_server": "192.168.11.3",
"mqtt_port": "1883",
"mqtt_user": "",
"mqtt_pass": "",
"mqtt_topic": "01234567890123456789",
"gateway_name": "01234567890123456789012345678901234567890123456789012345678901234567890123456789",
"mqtt_broker_secure": false,
"mqtt_broker_cert": "",
"mqtt_ss_index": 0,
"ota_server_cert": ""
}W: MQTT connection...
N: Connected to broker
Stack smashing protect failure!
abort() was called at PC 0x40190827 on core 1
ELF file SHA256: 0000000000000000
Backtrace: 0x4008fac4:0x3ffcdd60 0x4008fd41:0x3ffcdd80 0x40190827:0x3ffcdda0 0x400d412a:0x3ffcddc0 0x400dac3d:0x3ffcded0 0x401068a4:0x3ffcdef0 0x40090d52:0x3ffcdf10
Rebooting...
I'm recompiling OMG without *2 to test.
BTW, if source char* is the same size as max len strncpy does not terminate the dest char* with \0, so all static allocation should be at least len+1 and last char forced to \0.
Bad
Thanks for pointing that out, any idea @h2zero ?
Bad looks to have sorted it out 😄
Hello Guys,
I had quite a struggle with PlatformIO... but anyway:
As I suspected, gw & topic change is working without the *2, but still some overflow with long names:
N: [ MQTT->OMG ]: {"gateway_name":"omg34567890123456789012345678901234567890123456789012345678901234567890123456789","mqtt_topic":"home/"}
{
"mqtt_server": "192.168.11.3",
"mqtt_port": "1883",
"mqtt_user": "your_username",
"mqtt_pass": "your_password",
"mqtt_topic": "home/",
"gateway_name": "omg345678901234567890123456789012345678901234567890123456789home/",
"mqtt_broker_secure": false,
"mqtt_broker_cert": "",
"mqtt_ss_index": 0,
"ota_server_cert": ""
}
There are a lot of unsafe strcpy/strcat/strcmp especially regarding mqtt_topic & gateway_name...
But I will suggest a PR to fix explicitly this issue first by:
- limiting
mqtt_topic&gateway_nametoparameters_sizeinstead ofmqtt_topic_max_size, and - declaring
mqtt_topic&gateway_namewith a size ofparameters_size + 1, - increasing
mqtt_topic_max_sizefrom100to150for common platforms (ESP8266,ESP32,__AVR_ATmega2560__&__AVR_ATmega1280__) and from50to75for others (even if max size for a MQTT topic is 65536 bytes). So that at least<max mqtt_topic><max gateway_name>/commands/MQTTtoSYS/configcould fit in it.
With that even with a very large mqtt_topic & gateway_name, topic can still be redefined:
N: [ MQTT->OMG ]: {"gateway_name":"omg34567890123456789012345678901234567890123456789012345678901234567890123456789","mqtt_topic":"01234567890123456789012345678901234567890123456789012345678/"}
{
"mqtt_server": "192.168.11.3",
"mqtt_port": "1883",
"mqtt_user": "your_username",
"mqtt_pass": "your_password",
"mqtt_topic": "01234567890123456789012345678901234567890123456789012345678/",
"gateway_name": "omg345678901234567890123456789012345678901234567890123456789",
"mqtt_broker_secure": false,
"mqtt_broker_cert": "",
"mqtt_ss_index": 0,
"ota_server_cert": ""
}
And is correctly truncated:
N: [ MQTT->OMG ]: {"gateway_name":"omg345678901234567890123456789012345678901234567890123456789012345678901234567890123456789","mqtt_topic":"0123456789012345678901234567890123456789012345678901234567890123456789/"}
{
"mqtt_server": "192.168.11.3",
"mqtt_port": "1883",
"mqtt_user": "your_username",
"mqtt_pass": "your_password",
"mqtt_topic": "012345678901234567890123456789012345678901234567890123456789",
"gateway_name": "omg345678901234567890123456789012345678901234567890123456789",
"mqtt_broker_secure": false,
"mqtt_broker_cert": "",
"mqtt_ss_index": 0,
"ota_server_cert": ""
}
Are you ok with that, or should I address at the same time unsafe strcpy/strcat/strcmp ?
I would also suggest to reduce parameters_size, or (m)allocate it on the heap, or simply use C++ String.
Bad
Hello,
PR #1242 has been merged and integrated in v0.9.15.
It handles almost all points:
- limiting
mqtt_topic&gateway_nametoparameters_sizeinstead ofmqtt_topic_max_size, - declaring
mqtt_topic&gateway_namewith a size ofparameters_size + 1, - increasing
mqtt_topic_max_sizefrom100to150for common platforms and from50to75for others, - rewrite cmpToMainTopic() function to be safer (and faster) when comparing C-strings.
But not:
- unsafe strcpy/strcat especially regarding
mqtt_topic&gateway_name, - handle better
mqtt_topic&gateway_nameby (m)allocating it on the heap, or using C++ String.
Those points are minor from my perspective. So, should we close this issue or do you want me to address them in a new PR?
Bad
Hello,
@h2zero what are your thoughts here?
This issue is stale because it has been open for 30 days with no activity.
This issue was closed because it has been inactive for 14 days since being marked as stale.