From b77e7b6b217860e166081f8a93fb8bac81797897 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 13 Mar 2020 09:34:00 -0700 Subject: [PATCH] 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 Debugged-by: Jef Driesen Signed-off-by: Linus Torvalds --- src/iostream.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/iostream.c b/src/iostream.c index 7505495..7d0040d 100644 --- a/src/iostream.c +++ b/src/iostream.c @@ -215,6 +215,15 @@ dc_iostream_read (dc_iostream_t *iostream, void *data, size_t size, size_t *actu if (status != DC_STATUS_SUCCESS) 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, * since the reader is not able to handle a