fix: upstream security and robustness fixes (MACThenDecrypt alignment, CLI buffer, packet pool, raw data paths, ESP32 time after reset, Bosch sensor address)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Jakub
2026-10-12 19:53:53 +02:00
co-authored by Claude Opus 5.5
parent ec42a74ab6
commit 18f5627b2a
11 changed files with 130 additions and 35 deletions
+23 -11
View File
@@ -2065,16 +2065,20 @@ void MyMesh::handleCmdFrame(size_t len) {
#endif
} else if (cmd_frame[0] == CMD_SEND_RAW_DATA && len >= 6) {
int i = 1;
int8_t path_len = cmd_frame[i++];
if (path_len >= 0 && i + path_len + 4 <= len) { // minimum 4 byte payload
uint8_t *path = &cmd_frame[i];
i += path_len;
auto pkt = createRawData(&cmd_frame[i], len - i);
if (pkt) {
sendDirect(pkt, path, path_len);
writeOKFrame();
uint8_t path_len = cmd_frame[i++]; // encoded: hash size in the top bits (upstream 0cce9197 / 67d6d42a)
if (mesh::Packet::isValidPathLen(path_len)) {
uint8_t path[MAX_PATH_SIZE];
i += mesh::Packet::writePath(path, &cmd_frame[i], path_len);
if (i + 4 > len) { // min payload 4 bytes
writeErrFrame(ERR_CODE_ILLEGAL_ARG);
} else {
writeErrFrame(ERR_CODE_TABLE_FULL);
auto pkt = createRawData(&cmd_frame[i], len - i);
if (pkt) {
sendDirect(pkt, path, path_len);
writeOKFrame();
} else {
writeErrFrame(ERR_CODE_TABLE_FULL);
}
}
} else {
writeErrFrame(ERR_CODE_UNSUPPORTED_CMD); // flood, not supported (yet)
@@ -2634,6 +2638,13 @@ void MyMesh::enterCLIRescue() {
void MyMesh::checkCLIRescueCmd() {
int len = strlen(cli_command);
// `cli_command` must stay NUL-terminated within its bounds. If it ever isn't,
// strlen() above can return >= sizeof(cli_command) and the loop below would
// then index past the buffer, so clamp defensively.
if (len >= (int)sizeof(cli_command)) {
cli_command[0] = 0;
len = 0;
}
while (Serial.available() && len < sizeof(cli_command)-1) {
char c = Serial.read();
if (c != '\n') {
@@ -2642,8 +2653,9 @@ void MyMesh::checkCLIRescueCmd() {
}
Serial.print(c); // echo
}
if (len == sizeof(cli_command)-1) { // command buffer full
cli_command[sizeof(cli_command)-1] = '\r';
if (len == sizeof(cli_command)-1) { // buffer full: treat as a completed line
cli_command[sizeof(cli_command)-2] = '\r'; // place end-of-line marker inside the buffer
cli_command[sizeof(cli_command)-1] = 0; // keep the buffer NUL-terminated
}
if (len > 0 && cli_command[len - 1] == '\r') { // received complete line
+10 -2
View File
@@ -204,6 +204,13 @@ void setup() {
void loop() {
// Handle Serial CLI
int len = strlen(command);
// `command` must stay NUL-terminated within its bounds. If it ever isn't,
// strlen() above can return >= sizeof(command) and the loop below would then
// index past the buffer, so clamp defensively.
if (len >= (int)sizeof(command)) {
command[0] = 0;
len = 0;
}
while (Serial.available() && len < sizeof(command)-1) {
char c = Serial.read();
if (c != '\n') {
@@ -213,8 +220,9 @@ void loop() {
}
if (c == '\r') break;
}
if (len == sizeof(command)-1) { // command buffer full
command[sizeof(command)-1] = '\r';
if (len == sizeof(command)-1) { // buffer full: treat as a completed line
command[sizeof(command)-2] = '\r'; // place end-of-line marker inside the buffer
command[sizeof(command)-1] = 0; // keep the buffer NUL-terminated
}
if (len > 0 && command[len - 1] == '\r') { // received complete line
+10 -2
View File
@@ -142,6 +142,13 @@ void setup() {
void loop() {
int len = strlen(command);
// `command` must stay NUL-terminated within its bounds. If it ever isn't,
// strlen() above can return >= sizeof(command) and the loop below would then
// index past the buffer, so clamp defensively.
if (len >= (int)sizeof(command)) {
command[0] = 0;
len = 0;
}
while (Serial.available() && len < sizeof(command)-1) {
char c = Serial.read();
if (c != '\n') {
@@ -150,8 +157,9 @@ void loop() {
}
Serial.print(c);
}
if (len == sizeof(command)-1) { // command buffer full
command[sizeof(command)-1] = '\r';
if (len == sizeof(command)-1) { // buffer full: treat as a completed line
command[sizeof(command)-2] = '\r'; // place end-of-line marker inside the buffer
command[sizeof(command)-1] = 0; // keep the buffer NUL-terminated
}
if (len > 0 && command[len - 1] == '\r') { // received complete line
+10 -2
View File
@@ -529,6 +529,13 @@ public:
BaseChatMesh::loop();
int len = strlen(command);
// `command` must stay NUL-terminated within its bounds. If it ever isn't,
// strlen() above can return >= sizeof(command) and the loop below would then
// index past the buffer, so clamp defensively.
if (len >= (int)sizeof(command)) {
command[0] = 0;
len = 0;
}
while (Serial.available() && len < sizeof(command)-1) {
char c = Serial.read();
if (c != '\n') {
@@ -537,8 +544,9 @@ public:
}
Serial.print(c);
}
if (len == sizeof(command)-1) { // command buffer full
command[sizeof(command)-1] = '\r';
if (len == sizeof(command)-1) { // buffer full: treat as a completed line
command[sizeof(command)-2] = '\r'; // place end-of-line marker inside the buffer
command[sizeof(command)-1] = 0; // keep the buffer NUL-terminated
}
if (len > 0 && command[len - 1] == '\r') { // received complete line
+10 -2
View File
@@ -122,6 +122,13 @@ void setup() {
void loop() {
int len = strlen(command);
// `command` must stay NUL-terminated within its bounds. If it ever isn't,
// strlen() above can return >= sizeof(command) and the loop below would then
// index past the buffer, so clamp defensively.
if (len >= (int)sizeof(command)) {
command[0] = 0;
len = 0;
}
while (Serial.available() && len < sizeof(command)-1) {
char c = Serial.read();
if (c != '\n') {
@@ -130,8 +137,9 @@ void loop() {
}
Serial.print(c);
}
if (len == sizeof(command)-1) { // command buffer full
command[sizeof(command)-1] = '\r';
if (len == sizeof(command)-1) { // buffer full: treat as a completed line
command[sizeof(command)-2] = '\r'; // place end-of-line marker inside the buffer
command[sizeof(command)-1] = 0; // keep the buffer NUL-terminated
}
if (len > 0 && command[len - 1] == '\r') { // received complete line