iostream: protect against bad custom interfaces

Jef Driesen points out that the subsurface custom iostream read function
for legacy bluetooth can return a "success" with zero bytes actually
read.  That makes the loop we have to fill up the whole buffer very unhappy.

That's definitely a bug on the subsurface side, but let's also be
defensive about it in the iostream layer.

Note that this happens only when the reader is not able to handle
partial packets (doesn't pass in an "actual" pointer), and we haven't
gotten a full packet yet.

So we'll turn it into a DC_STATUS_TIMEOUT, which is debatable, but the
real fix is for subsurface to not do this in its rfcomm iostream
implementation, and instead return the proper error code.

Reported-by: linuxcrash <albin@mrty.ch>
Debugged-by: Jef Driesen <jef@libdivecomputer.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
Linus Torvalds 2020-03-13 09:34:00 -07:00
parent 0714e327b7
commit b77e7b6b21

View File

@ -215,6 +215,15 @@ dc_iostream_read (dc_iostream_t *iostream, void *data, size_t size, size_t *actu
if (status != DC_STATUS_SUCCESS) if (status != DC_STATUS_SUCCESS)
return status; return status;
/*
* Defensive check: if the read() function returned
* zero bytes, don't loop forever - give up with a
* timeout. Jef pointed out that the subsurface
* qt_serial_read() function can cause this badness..
*/
if (!nbytes)
return DC_STATUS_TIMEOUT;
/* /*
* Continue reading to fill up the whole buffer, * Continue reading to fill up the whole buffer,
* since the reader is not able to handle a * since the reader is not able to handle a