goToMain / libosdp

Implementation of IEC 60839-11-5 OSDP (Open Supervised Device Protocol); provides a C library with support for C++, Rust and Python3
https://libosdp.sidcha.dev
Apache License 2.0
138 stars 71 forks source link

Avoid receiving invalid data by flushing rx before each send. #36

Closed te-johan closed 3 years ago

te-johan commented 3 years ago

While doing some fuzzing I ran into an interesting issue. I run two PD on the same wires and introduced some bad data on the wires. When doing so I was able to get the serial device out of sync with the channel lock. What happens is that CP sends a command and immediately it receives some invalid data. This triggers error cleanup which flushes the RX queue. However this flush happens before it gets its reply so in the RX queue there now is a complete reply to the command.

Next the channel lock will be released and the next command will receive the reply from the other PD because the reply was was already in the RX queue. The CP never recovers from this since will be continue and send a command to PD A and B and receive the wrong reply every time.

I solve this issue by always flushing the RX queue before sending a command. An alternative solution can be can be to introduce an additional error state that waits for a timeout until it releases the lock and flushes the channel. Always flushing RX might seem excessive but I prefer to just keep it simple and not add any more states.