This vulnerability in the nanoMODBUS library exposes a dangerous API contract violation. The function accepts a buffers_length parameter specifically to tell the library how much space the caller allocated. You would reasonably expect the library to respect this constraint — it doesn't.
The code validates only against res_size_left (ensuring what the server sent fits in the PDU), while completely ignoring buffers_length during the critical NUL-terminator write. The strncpy call itself is bounded correctly, which creates an illusion of safety — developers who skim the code see the bounded copy and may believe the buffer cannot overflow. But the unconditional NUL write at buffers_out[buf_index][object_length] occurs after the bounded copy, bypassing the safety you thought you had.
Note that the terminator placement itself is server-controlled — it writes at object_length, not at buffers_length - 1. Even a naive fix adding object_length < buffers_length validation doesn't fully solve this: the terminator can still land anywhere from index 0 to buffers_length - 1. The correct fix either truncates object_length to buffers_length - 1 before the copy, or ensures the NUL always writes at buffers_length - 1 regardless of what the server supplied.
This pattern — bounded copy followed by unconditional terminator — defeats developer intuition consistently. The API gives with one hand (bounded strncpy) and takes away with the other (unbounded terminator). The buffers_length parameter exists in the function signature but is never consulted for the dangerous operation.
In industrial Modbus TCP deployments, this matters significantly. Client-side code often runs against servers that may be compromised or misconfigured. The client must validate server responses against caller-provided buffer constraints — not just PDU structure. The fix is straightforward: validate that the server-supplied length fits within your caller-supplied buffer before performing any write.