What happened?
This tickets collects several potential memory access problems that popped up during code reviews of PRs.
case 1 (not a bug)
wled00/util.cpp 404-405: Out‑of‑bounds write: null‑terminator placed past buffer end.
Use maxLen‑1 index.
- dest[maxLen] = '\0'; // strncpy does not necessarily null terminate string
+ dest[maxLen-1] = '\0'; // ensure termination within bounds
--> not a bug; only called from rotary usermod, with dest[64] and maxLen=63
case 2 (confirmed)
wled00/util.cpp 374-377: Dangling pointer from temporary String (use‑after‑free).
names.substring(...).c_str() returns a pointer to a temporary; it’s invalid by the next statement. Keep a String alive for the copy.
- if (nameEnd<0) tmpstr = names.substring(nameBegin).c_str(); // did not find ",", last name?
- else tmpstr = names.substring(nameBegin, nameEnd).c_str();
- strlcpy(dest, tmpstr, maxLen); // copy the name into buffer (replacing previous)
+ {
+ String sub = (nameEnd < 0) ? names. Substring(nameBegin)
+ : names.substring(nameBegin, nameEnd);
+ strlcpy(dest, sub.c_str(), maxLen); // copy name into buffer
+ }
case 3 (not a bug)
wled00/util.cpp 293-299: Fix off‑by‑one NUL write in extractModeName.
When j reaches maxLen, dest[j] writes one past the buffer.
Apply:
- for (; j < maxLen && j < len; j++) {
+ for (; (j + 1) < maxLen && j < len; j++) {
if (lineBuffer[j] == '\0' || lineBuffer[j] == '@') break;
dest[j] = lineBuffer[j];
}
- dest[j] = 0; // terminate string
+ dest[j] = '\0'; // terminate string
--> not a bug; called from several usermods; verified that maxLen is always len-1 (safe).
case 4 (confirmed)
wled00/ir.cpp 676-685: Potential buffer overflow in objKey formatting
""0x%lX":" can be up to 13 chars for 0xFFFFFFFF (plus NUL). objKey[10] is too small. Use a larger buffer and snprintf.
- char objKey[10];
+ char objKey[16];
@@
- sprintf_P(objKey, PSTR("\"0x%lX\":"), (unsigned long)code);
+ snprintf_P(objKey, sizeof(objKey), PSTR("\"0x%lX\":"), (unsigned long)code);
case 5 (to be analyzed)
wled00/ir.cpp 186-186: possible Bug: writing intensity into speed
Should assign intensity, not speed, when not applying to all segments.
- strip.getMainSegment().speed = effectIntensity;
+ strip.getMainSegment().intensity = effectIntensity;
case 6 (not a bug)
wled00/util.cpp 162-177: Fix off-by-one overflow in oappend() null terminator check
(from #152 (review))
strcpy() writes a trailing '\0'. The current capacity check doesn’t reserve space for it; when olen + len == SETTINGS_STACK_BUF_SIZE - 1, the '\0' writes out of bounds.
Apply:
- if ((obuf == nullptr) || (olen + len >= SETTINGS_STACK_BUF_SIZE)) { // sanity checks
+ if ((obuf == nullptr) || (olen + len + 1 > SETTINGS_STACK_BUF_SIZE)) { // reserve room for '\0'
Optionally use strlcpy:
- strcpy(obuf + olen, finalTxt);
- olen += len;
+ olen += strlcpy(obuf + olen, finalTxt, SETTINGS_STACK_BUF_SIZE - olen);
--> not a bug, the only "obuf" that's close to the stack buffer limit is in serveSettingsJS() with char buf[SETTINGS_STACK_BUF_SIZE+37]
plus
fixes for usermods, see #270 (comment)
What version/release of MM WLED?
mdev latest in development
Which microcontroller/board are you seeing the problem on?
Other, ESP32
Code of Conduct
What happened?
This tickets collects several potential memory access problems that popped up during code reviews of PRs.
case 1 (not a bug)
wled00/util.cpp 404-405: Out‑of‑bounds write: null‑terminator placed past buffer end.
Use maxLen‑1 index.
--> not a bug; only called from rotary usermod, with dest[64] and maxLen=63
case 2 (confirmed)
wled00/util.cpp 374-377: Dangling pointer from temporary String (use‑after‑free).
names.substring(...).c_str() returns a pointer to a temporary; it’s invalid by the next statement. Keep a String alive for the copy.
case 3 (not a bug)
wled00/util.cpp 293-299: Fix off‑by‑one NUL write in extractModeName.
When j reaches maxLen, dest[j] writes one past the buffer.
Apply:
--> not a bug; called from several usermods; verified that maxLen is always len-1 (safe).
case 4 (confirmed)
wled00/ir.cpp 676-685: Potential buffer overflow in objKey formatting
""0x%lX":" can be up to 13 chars for 0xFFFFFFFF (plus NUL). objKey[10] is too small. Use a larger buffer and snprintf.
case 5 (to be analyzed)
wled00/ir.cpp 186-186: possible Bug: writing intensity into speed
Should assign intensity, not speed, when not applying to all segments.
case 6 (not a bug)
wled00/util.cpp 162-177: Fix off-by-one overflow in oappend() null terminator check
(from #152 (review))
strcpy() writes a trailing '\0'. The current capacity check doesn’t reserve space for it; when olen + len == SETTINGS_STACK_BUF_SIZE - 1, the '\0' writes out of bounds.
Apply:
--> not a bug, the only "obuf" that's close to the stack buffer limit is in serveSettingsJS() with
char buf[SETTINGS_STACK_BUF_SIZE+37]plus
fixes for usermods, see #270 (comment)
What version/release of MM WLED?
mdev latest in development
Which microcontroller/board are you seeing the problem on?
Other, ESP32
Code of Conduct