MMU Serial Port issue. Unsafe write() function #4814
Replies: 4 comments 6 replies
-
SERIOUSLY? No one cares about this? |
Beta Was this translation helpful? Give feedback.
-
I added a simple function to the MMU2 namespace: void MMU2Serial::print(String TextToPrint) And call it from a number of places in the Firmware. However, I was getting "FW crash detected", numerous times. I did indeed have a number of text strings that I was sending via my MU2Serial::print() function which were greater than 20 bytes. It SEEMED to me that maybe that buffer size was the problem. So I sent a sequence of strings via my MMU2Serial::print() function, starting with just one character and working its way up to more-than-20. Everything was going fine but when it hit the string that was longer than 20 characters up popped the "FW crash detected" message again. So I went through all my code and shortened any string that was being sent via my MMU2Serial::print() function to being less than 20 characters. And having done that, no more "FW crash detected" errors. So somehow there does seem to be a 20-character limit, somehow. You mention that "MMU2Serial::write calls uart2_putchar() through fputc which sends one byte at time regardless of the buffer size." And it seems that uart2_putchar WAITS for the uart2_txready. Does that mean that it waits for any previously sent character to be RECEIVED on the receiving end? In that uart2_putchar() function you reference: int uart2_putchar(char c, _UNUSED FILE *stream) there is also a commented-out couple of instructions, and it references uart2_txcomplete. Is there a difference between uart2_txready and uart2_txcomplete, such that uart2_txready doesn't really wait for the text to have been sent? Could that be the cause of the "FW crash detected" messages I'd been getting whenever one of the messages I was sending was greater than 20 characters? The testing that I did sure did seem to indicate that there's a 20-character limit SOMEWHERE. |
Beta Was this translation helpful? Give feedback.
-
Thank you so much for taking the time to look through this issue. |
Beta Was this translation helpful? Give feedback.
-
FYI: We just merged some minor cleanup on the Uart code #4816 Hopefully less code “noise” :) |
Beta Was this translation helpful? Give feedback.
-
I'm looking at the serial port function for the MMU in the latest version of the MK3 Open Source code, and I think there's a coding problem with the write() function of the MMU serial port on my PRUSA MK3S., which is this:
void MMU2Serial::write(const uint8_t *buffer, size_t size)
{
while(size--){
fputc(*buffer, uart2io);
++buffer;
}
}
In the related uart2.c file it defines uart2io_ibuf in this way:
uint8_t uart2_ibuf[20] = {0, 0};
It doesn't look right to me. In particular the buffer is defined as 20 bytes but the write function writes into it with whatever is passed as the size parameter, meaning it could easily overwrite the buffer. Now, maybe there's some protocol or rules that the PRUSA programmers are supposed to follow (e.g. "No text more than 20 characters long to be used in calls to the write() function), but shouldn't the code itself do something if the text is too long? It just doesn't look like a very safe function.
In fact I have been making some modifications to the firmware and did indeed inadvertently write longer-than-20-characters to the write() function and the program crashes with an "FW crash detected" error.
I asked ChatGPT about it and it responded with this, which verified my concerns, but raised additional issues:
The uart2_ibuf buffer is defined as uint8_t uart2_ibuf[20], which is only 20 bytes in size. If write tries to send more than 20 bytes at once, it could lead to a buffer overflow when accessing uart2io.
Confirm whether uart2io is properly configured to handle more data or whether fputc ensures safe handling of larger input.
If the write function is called from multiple threads or interrupts, and fputc or uart2io isn't thread-safe, race conditions could occur.
If fputc does not block until the byte is transmitted, it could overwrite previous data or lose some of it. Ensure fputc properly waits for the UART transmission buffer to be ready.
The function decrements size until it reaches 0, but there's no validation of the size against the capabilities of fputc or uart2io. If size is very large, performance could degrade or memory corruption might occur.Potential Problems:
Beta Was this translation helpful? Give feedback.
All reactions