From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.2 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_SANE_1 autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B9143C433FE for ; Wed, 9 Dec 2020 10:28:09 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 8810B23B6B for ; Wed, 9 Dec 2020 10:28:09 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729884AbgLIK2F (ORCPT ); Wed, 9 Dec 2020 05:28:05 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55636 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725933AbgLIK2E (ORCPT ); Wed, 9 Dec 2020 05:28:04 -0500 X-Greylist: delayed 60 seconds by postgrey-1.37 at lindbergh.monkeyblade.net; Wed, 09 Dec 2020 02:27:24 PST Received: from hera.aquilenet.fr (hera.aquilenet.fr [IPv6:2a0c:e300::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A2F3CC0613CF for ; Wed, 9 Dec 2020 02:27:24 -0800 (PST) Received: from localhost (localhost [127.0.0.1]) by hera.aquilenet.fr (Postfix) with ESMTP id 6814D14C1 for ; Wed, 9 Dec 2020 11:26:42 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at aquilenet.fr Received: from hera.aquilenet.fr ([127.0.0.1]) by localhost (hera.aquilenet.fr [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id l4DoY6IpLcnl for ; Wed, 9 Dec 2020 11:26:41 +0100 (CET) Received: from function.youpi.perso.aquilenet.fr (unknown [IPv6:2a01:cb19:956:1b00:9eb6:d0ff:fe88:c3c7]) by hera.aquilenet.fr (Postfix) with ESMTPSA id 70FFE14B0 for ; Wed, 9 Dec 2020 11:26:41 +0100 (CET) Received: from samy by function.youpi.perso.aquilenet.fr with local (Exim 4.94) (envelope-from ) id 1kmwgC-005zrr-Us for stable@vger.kernel.org; Wed, 09 Dec 2020 11:26:40 +0100 Date: Wed, 9 Dec 2020 11:26:40 +0100 From: Samuel Thibault To: stable@vger.kernel.org Subject: [PATCH for 4.19] speakup: Reject setting the speakup line discipline outside of speakup Message-ID: <20201209102640.yn7mdn52sm7bfbgm@function> Mail-Followup-To: Samuel Thibault , stable@vger.kernel.org MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: NeoMutt/20170609 (1.8.3) Precedence: bulk List-ID: X-Mailing-List: stable@vger.kernel.org [backport of 5.10 commit f0992098cadb4c9c6a00703b66cafe604e178fea] Speakup exposing a line discipline allows userland to try to use it, while it is deemed to be useless, and thus uselessly exposes potential bugs. One of them is simply that in such a case if the line sends data, spk_ttyio_receive_buf2 is called and crashes since spk_ttyio_synth is NULL. This change restricts the use of the speakup line discipline to speakup drivers, thus avoiding such kind of issues altogether. Cc: stable@vger.kernel.org Reported-by: Shisong Qin Signed-off-by: Samuel Thibault Tested-by: Shisong Qin Link: https://lore.kernel.org/r/20201129193523.hm3f6n5xrn6fiyyc@function Signed-off-by: Greg Kroah-Hartman diff --git a/drivers/staging/speakup/spk_ttyio.c b/drivers/staging/speakup/spk_ttyio.c index 669392f31d4e..6284aff434a1 100644 --- a/drivers/staging/speakup/spk_ttyio.c +++ b/drivers/staging/speakup/spk_ttyio.c @@ -47,27 +47,20 @@ static int spk_ttyio_ldisc_open(struct tty_struct *tty) { struct spk_ldisc_data *ldisc_data; + if (tty != speakup_tty) + /* Somebody tried to use this line discipline outside speakup */ + return -ENODEV; + if (tty->ops->write == NULL) return -EOPNOTSUPP; - mutex_lock(&speakup_tty_mutex); - if (speakup_tty) { - mutex_unlock(&speakup_tty_mutex); - return -EBUSY; - } - speakup_tty = tty; - ldisc_data = kmalloc(sizeof(struct spk_ldisc_data), GFP_KERNEL); - if (!ldisc_data) { - speakup_tty = NULL; - mutex_unlock(&speakup_tty_mutex); + if (!ldisc_data) return -ENOMEM; - } sema_init(&ldisc_data->sem, 0); ldisc_data->buf_free = true; - speakup_tty->disc_data = ldisc_data; - mutex_unlock(&speakup_tty_mutex); + tty->disc_data = ldisc_data; return 0; } @@ -191,9 +184,25 @@ static int spk_ttyio_initialise_ldisc(struct spk_synth *synth) tty_unlock(tty); + mutex_lock(&speakup_tty_mutex); + speakup_tty = tty; ret = tty_set_ldisc(tty, N_SPEAKUP); if (ret) - pr_err("speakup: Failed to set N_SPEAKUP on tty\n"); + speakup_tty = NULL; + mutex_unlock(&speakup_tty_mutex); + + if (!ret) + /* Success */ + return 0; + + pr_err("speakup: Failed to set N_SPEAKUP on tty\n"); + + tty_lock(tty); + if (tty->ops->close) + tty->ops->close(tty, NULL); + tty_unlock(tty); + + tty_kclose(tty); return ret; }