[patch 1/1] staging: speakup: fix async usb removal

Okash Khawaja okash.khawaja at gmail.com
Sat Aug 5 13:56:01 EDT 2017


When an external USB synth is unplugged while the module is loaded, we
get a null pointer deref. This is because the tty disappears while
speakup tries to use to to communicate with the synth. This patch fixes
it by checking tty for null before using it. In case of error, it sets
synth->alive to zero and starts ttys. It also updates catch_up kthread
to check for synth->alive whenever synth_out fails. This way, when
synth_out fails, catch_up thread won't be looping forever.

Signed-off-by: Okash Khawaja <okash.khawaja at gmail.com>

---
 drivers/staging/speakup/spk_ttyio.c |   25 +++++++++++++++++++++++++
 1 file changed, 25 insertions(+)

--- a/drivers/staging/speakup/spk_ttyio.c
+++ b/drivers/staging/speakup/spk_ttyio.c
@@ -210,13 +210,35 @@ static int spk_ttyio_out(struct spk_synt
 	return 0;
 }
 
+static int check_tty(struct tty_struct *tty)
+{
+	if (!tty) {
+		pr_warn("%s: I/O error, deactivating speakup\n", spk_ttyio_synth->long_name);
+		/* No synth any more, so nobody will restart TTYs, and we thus
+		 * need to do it ourselves.  Now that there is no synth we can
+		 * let application flood anyway
+		 */
+		spk_ttyio_synth->alive = 0;
+		speakup_start_ttys();
+		return 1;
+	}
+
+	return 0;
+}
+
 static void spk_ttyio_send_xchar(char ch)
 {
+	if (check_tty(speakup_tty))
+		return;
+
 	speakup_tty->ops->send_xchar(speakup_tty, ch);
 }
 
 static void spk_ttyio_tiocmset(unsigned int set, unsigned int clear)
 {
+	if (check_tty(speakup_tty))
+		return;
+
 	speakup_tty->ops->tiocmset(speakup_tty, set, clear);
 }
 
@@ -257,6 +279,9 @@ static unsigned char spk_ttyio_in_nowait
 
 static void spk_ttyio_flush_buffer(void)
 {
+	if (check_tty(speakup_tty))
+		return;
+
 	if (speakup_tty->ops->flush_buffer)
 		speakup_tty->ops->flush_buffer(speakup_tty);
 }



More information about the Speakup mailing list