From patchwork Tue Jan 8 20:18:45 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Guilherme G. Piccoli" X-Patchwork-Id: 1022120 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=canonical.com Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43Z3WF3hfKz9sCr; Wed, 9 Jan 2019 07:19:05 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1ggxq0-000833-A4; Tue, 08 Jan 2019 20:19:00 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by huckleberry.canonical.com with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:128) (Exim 4.86_2) (envelope-from ) id 1ggxpx-00082O-J8 for kernel-team@lists.ubuntu.com; Tue, 08 Jan 2019 20:18:57 +0000 Received: from mail-qt1-f197.google.com ([209.85.160.197]) by youngberry.canonical.com with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.76) (envelope-from ) id 1ggxpx-0007UC-9O for kernel-team@lists.ubuntu.com; Tue, 08 Jan 2019 20:18:57 +0000 Received: by mail-qt1-f197.google.com with SMTP id u20so4521575qtk.6 for ; Tue, 08 Jan 2019 12:18:57 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=1o1o0Ug0GAWcs5Gl+laDTcsMMZo0om4SOjIazOijEf8=; b=ogDBqBCWhyRYbAFPmd1pwxX5ams19kZUgyp295lY5+/3TZctkj//Kt/GEA4llNeMji KHwQ4ZVX/zyXmDjbwjl3sj/IGiG5baMCTOgI6pjKBjfp70zTQ3fI9C89aZP8H5PP4BU7 Pqfsdxg8L2zZb0Oy8wR74TJWBglbq3NuS9UT7225rxocT6I2HQU3sxtff8/Wn7l3VHSz 8av84ZoKrAX0Us/k847YCV6Gj59ZqZt9y/UMOaOTmG/8S7RB/f5s3C05Txg9Jg6ImpQh thHYDUxkfg1/k2jpNWPliWfiRdjF5zZd0tyxRvr5QRgl5OshndRoTVdrqaE/5XAlzxia RUZA== X-Gm-Message-State: AJcUukdcve/gbYgkSuu/kIJcR+q6U71tV7MqXefO6hORya4xm02/Esam c2M07yH1aJc0i4SswWrdk+5453XHjSWPquiNdyCXG5RNiwxSWp49c1sGZo4btSq7U6/a8YuCFWo MBilAJTt3Nn19zI2Vfy3jueu3o2TKkGt3rk6VEXRedA== X-Received: by 2002:a0c:b746:: with SMTP id q6mr3057214qve.235.1546978736211; Tue, 08 Jan 2019 12:18:56 -0800 (PST) X-Google-Smtp-Source: ALg8bN4jCqyX0ArWs6AsFysaSdGYj5AWq6PYUEThuD6nGcLElQOIUSczT+sS4H3mzgAmb3ZLMAKj0w== X-Received: by 2002:a0c:b746:: with SMTP id q6mr3057203qve.235.1546978735979; Tue, 08 Jan 2019 12:18:55 -0800 (PST) Received: from localhost ([191.13.50.232]) by smtp.gmail.com with ESMTPSA id m68sm32684520qte.49.2019.01.08.12.18.55 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 08 Jan 2019 12:18:55 -0800 (PST) From: "Guilherme G. Piccoli" To: kernel-team@lists.ubuntu.com Subject: [SRU X] [PATCH 1/5] tty: fix data race between tty_init_dev and flush of buf Date: Tue, 8 Jan 2019 18:18:45 -0200 Message-Id: <20190108201849.11907-2-gpiccoli@canonical.com> X-Mailer: git-send-email 2.19.2 In-Reply-To: <20190108201849.11907-1-gpiccoli@canonical.com> References: <20190108201849.11907-1-gpiccoli@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: gpiccoli@canonical.com Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Gaurav Kohli BugLink: https://bugs.launchpad.net/bugs/1791758 There can be a race, if receive_buf call comes before tty initialization completes in n_tty_open and tty->disc_data may be NULL. CPU0 CPU1 ---- ---- 000|n_tty_receive_buf_common() n_tty_open() -001|n_tty_receive_buf2() tty_ldisc_open.isra.3() -002|tty_ldisc_receive_buf(inline) tty_ldisc_setup() Using ldisc semaphore lock in tty_init_dev till disc_data initializes completely. Signed-off-by: Gaurav Kohli Reviewed-by: Alan Cox Cc: stable Signed-off-by: Greg Kroah-Hartman (backported from b027e2298bd588d6fa36ed2eda97447fb3eac078 upstream) [gpiccoli: context adjustment, kept the __lockfunc mark in tty_ldisc_lock()] Signed-off-by: Guilherme G. Piccoli --- drivers/tty/tty_io.c | 7 +++++++ drivers/tty/tty_ldisc.c | 4 ++-- include/linux/tty.h | 2 ++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 3f44d28ae2da..2ed3d2add7d4 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -1551,6 +1551,9 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx) "%s: %s driver does not set tty->port. This will crash the kernel later. Fix the driver!\n", __func__, tty->driver->name); + retval = tty_ldisc_lock(tty, 5 * HZ); + if (retval) + goto err_release_lock; tty->port->itty = tty; /* @@ -1561,6 +1564,7 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx) retval = tty_ldisc_setup(tty, tty->link); if (retval) goto err_release_tty; + tty_ldisc_unlock(tty); /* Return the tty locked so that it cannot vanish under the caller */ return tty; @@ -1575,8 +1579,11 @@ err_module_put: /* call the tty release_tty routine to clean out this slot */ err_release_tty: tty_unlock(tty); + tty_ldisc_unlock(tty); printk_ratelimited(KERN_INFO "tty_init_dev: ldisc open failed, " "clearing slot %d\n", idx); +err_release_lock: + tty_unlock(tty); release_tty(tty, idx); return ERR_PTR(retval); } diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c index 7e3b725af8fa..fdc2c830a45c 100644 --- a/drivers/tty/tty_ldisc.c +++ b/drivers/tty/tty_ldisc.c @@ -325,7 +325,7 @@ static inline void __tty_ldisc_unlock(struct tty_struct *tty) ldsem_up_write(&tty->ldisc_sem); } -static int __lockfunc +int __lockfunc tty_ldisc_lock(struct tty_struct *tty, unsigned long timeout) { int ret; @@ -337,7 +337,7 @@ tty_ldisc_lock(struct tty_struct *tty, unsigned long timeout) return 0; } -static void tty_ldisc_unlock(struct tty_struct *tty) +void tty_ldisc_unlock(struct tty_struct *tty) { clear_bit(TTY_LDISC_HALTED, &tty->flags); __tty_ldisc_unlock(tty); diff --git a/include/linux/tty.h b/include/linux/tty.h index f2bfe07c983a..8927d8270620 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -374,6 +374,8 @@ extern struct tty_struct *get_current_tty(void); /* tty_io.c */ extern int __init tty_init(void); extern const char *tty_name(const struct tty_struct *tty); +extern int tty_ldisc_lock(struct tty_struct *tty, unsigned long timeout); +extern void tty_ldisc_unlock(struct tty_struct *tty); #else static inline void console_init(void) { } From patchwork Tue Jan 8 20:18:46 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Guilherme G. Piccoli" X-Patchwork-Id: 1022121 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=canonical.com Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43Z3WJ5dn8z9sCr; Wed, 9 Jan 2019 07:19:08 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1ggxq3-000850-F4; Tue, 08 Jan 2019 20:19:03 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by huckleberry.canonical.com with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:128) (Exim 4.86_2) (envelope-from ) id 1ggxq0-00083D-IE for kernel-team@lists.ubuntu.com; Tue, 08 Jan 2019 20:19:00 +0000 Received: from mail-qk1-f198.google.com ([209.85.222.198]) by youngberry.canonical.com with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.76) (envelope-from ) id 1ggxq0-0007Uk-8O for kernel-team@lists.ubuntu.com; Tue, 08 Jan 2019 20:19:00 +0000 Received: by mail-qk1-f198.google.com with SMTP id y27so4176156qkj.21 for ; Tue, 08 Jan 2019 12:19:00 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=wWdG+GMtzbcrUg0Pc/q3Qs0BeOnjeoRFT6zFM7R6vCU=; b=ovmsgJKQxVINZdBoyyGFlpUZcJtPWTUW3ntbpca0gdTR4PQUBeCDe5crZp/FBjKy7q At0nUvCGwKw7Ks2iN1p4A/kYKYARmTY8KFAScZgmVSqe1qTK2kkUw02zUiVVRp/pDo2C p6t19D/6yh21VEWUR94ZWOEnS6MGApmJGWAi/AAJ1w/6DL6U6GB1fjCI/LD+bPL/mS+2 M9O/NX9Jv/5F4manmwoygkPMcYB4yH39II5V6k/16HQAG8ZiIWRFeKv1SZGEv8qp6rcR rEmTkAFlndf0IKsSSiaQjWgZVGydcPGowcm6uRhNUqfyduxdDcjpYoxnntkYMJt1dJRM aTJQ== X-Gm-Message-State: AJcUukcqe93bhKaaqImOLZ7zRYfy4KzRcnKJI2AFjpKS/ozmDIiS+q8Y FEis35ZUdpOQZTGBV0v8rTn7rEj1ltxcdxVqgsyVrN5Od1MsE0X0BUFDXUDzjv4jrE0WtE1RvRe ZI9AJEbcvXFmmNDSAl/+mVqQKZEomX06kTshZ3FQ1KA== X-Received: by 2002:aed:39a1:: with SMTP id m30mr2980113qte.354.1546978739038; Tue, 08 Jan 2019 12:18:59 -0800 (PST) X-Google-Smtp-Source: ALg8bN5q6zwX4MIAbjtIieCoIeLC+FL8DG/+x0UEG4FeoUnU0BBishtnXA2iHJHX2NNDdqFs61Xcaw== X-Received: by 2002:aed:39a1:: with SMTP id m30mr2980095qte.354.1546978738757; Tue, 08 Jan 2019 12:18:58 -0800 (PST) Received: from localhost ([191.13.50.232]) by smtp.gmail.com with ESMTPSA id c12sm43377929qka.42.2019.01.08.12.18.57 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 08 Jan 2019 12:18:58 -0800 (PST) From: "Guilherme G. Piccoli" To: kernel-team@lists.ubuntu.com Subject: [SRU X] [PATCH 2/5] tty: Drop tty->count on tty_reopen() failure Date: Tue, 8 Jan 2019 18:18:46 -0200 Message-Id: <20190108201849.11907-3-gpiccoli@canonical.com> X-Mailer: git-send-email 2.19.2 In-Reply-To: <20190108201849.11907-1-gpiccoli@canonical.com> References: <20190108201849.11907-1-gpiccoli@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: gpiccoli@canonical.com Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Dmitry Safonov BugLink: https://bugs.launchpad.net/bugs/1791758 In case of tty_ldisc_reinit() failure, tty->count should be decremented back, otherwise we will never release_tty(). Tetsuo reported that it fixes noisy warnings on tty release like: pts pts4033: tty_release: tty->count(10529) != (#fd's(7) + #kopen's(0)) Fixes: commit 892d1fa7eaae ("tty: Destroy ldisc instance on hangup") Cc: stable@vger.kernel.org # v4.6+ Cc: Greg Kroah-Hartman Cc: Jiri Slaby Reviewed-by: Jiri Slaby Tested-by: Jiri Slaby Tested-by: Mark Rutland Tested-by: Tetsuo Handa Signed-off-by: Dmitry Safonov Signed-off-by: Greg Kroah-Hartman (cherry-picked from fe32416790093b31364c08395727de17ec96ace1 upstream) Signed-off-by: Guilherme G. Piccoli --- drivers/tty/tty_io.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 2ed3d2add7d4..d2f00378fc18 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -1474,6 +1474,7 @@ void tty_driver_remove_tty(struct tty_driver *driver, struct tty_struct *tty) static int tty_reopen(struct tty_struct *tty) { struct tty_driver *driver = tty->driver; + int retval; if (driver->type == TTY_DRIVER_TYPE_PTY && driver->subtype == PTY_TYPE_MASTER) @@ -1487,10 +1488,14 @@ static int tty_reopen(struct tty_struct *tty) tty->count++; - if (!tty->ldisc) - return tty_ldisc_reinit(tty, tty->termios.c_line); + if (tty->ldisc) + return 0; - return 0; + retval = tty_ldisc_reinit(tty, tty->termios.c_line); + if (retval) + tty->count--; + + return retval; } /** From patchwork Tue Jan 8 20:18:47 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Guilherme G. Piccoli" X-Patchwork-Id: 1022122 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=canonical.com Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43Z3WK2b0Cz9sMr; Wed, 9 Jan 2019 07:19:09 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1ggxq4-00085s-LM; Tue, 08 Jan 2019 20:19:04 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by huckleberry.canonical.com with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:128) (Exim 4.86_2) (envelope-from ) id 1ggxq3-00084k-4V for kernel-team@lists.ubuntu.com; Tue, 08 Jan 2019 20:19:03 +0000 Received: from mail-qk1-f199.google.com ([209.85.222.199]) by youngberry.canonical.com with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.76) (envelope-from ) id 1ggxq2-0007Vc-Qu for kernel-team@lists.ubuntu.com; Tue, 08 Jan 2019 20:19:02 +0000 Received: by mail-qk1-f199.google.com with SMTP id y83so4164394qka.7 for ; Tue, 08 Jan 2019 12:19:02 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=St8VJCafTTS2QHvdo/it6cDlGJVQImEnEG+s1e5boR4=; b=JitR4shwLTJx9yqKfgXDC6cp4LNq/7Ki1VGTUF3dD6ruOF7khnr/2zpq/kn9KbQITe s2fK0stWl17i/PuqXmgnk13wqeyJiL8IQaSyBoGSEcS9UiilQkwD/yW1AroSH9B3k6JT NPz7MW4VZoZEXGLYTlEOEDFhPgMA6bm5uIqkIj6dFBbJuoCwBTaUjXnl6n2N4dqxVYUE g0C5THV5BSvt9qaxZOO8EnoEZa+mRQFC8Y7V86lntyXqHYl+Vz5ZOhsAyjmYiAYRmDrh u15fk8guhoXmybHHFq/8kLKNjHNDXs5MmA+MY4a4kal6/4HXA4HXgp0b4efeeGbAoRyo WDBw== X-Gm-Message-State: AJcUukfvCbHfxtwQI1WVbJBVtQ8D0YlT9Km1z/SCQKDBQf0MWIbuWtsl 1gXtZ40yaP4TSg54GOWt5wuxI7FYxexfzaOWzCmb/KCQ40NI9eswml437gjA4InM2ZuTtOltgNy UVca6H5BZYY3jCU58Gn9dslvJEgZHFxHWfEZQoCGncg== X-Received: by 2002:a37:a44e:: with SMTP id n75mr3010017qke.26.1546978741582; Tue, 08 Jan 2019 12:19:01 -0800 (PST) X-Google-Smtp-Source: ALg8bN6gyJ4KhaZdU4rXrF4ER/dJdeI6AtMLLMUND67T9iRtw7CYRyFjj4KWpV+Eg2nusSLacPAAXw== X-Received: by 2002:a37:a44e:: with SMTP id n75mr3010006qke.26.1546978741409; Tue, 08 Jan 2019 12:19:01 -0800 (PST) Received: from localhost ([191.13.50.232]) by smtp.gmail.com with ESMTPSA id x57sm39579583qtx.96.2019.01.08.12.19.00 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 08 Jan 2019 12:19:00 -0800 (PST) From: "Guilherme G. Piccoli" To: kernel-team@lists.ubuntu.com Subject: [SRU X] [PATCH 3/5] tty: Hold tty_ldisc_lock() during tty_reopen() Date: Tue, 8 Jan 2019 18:18:47 -0200 Message-Id: <20190108201849.11907-4-gpiccoli@canonical.com> X-Mailer: git-send-email 2.19.2 In-Reply-To: <20190108201849.11907-1-gpiccoli@canonical.com> References: <20190108201849.11907-1-gpiccoli@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: gpiccoli@canonical.com Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Dmitry Safonov BugLink: https://bugs.launchpad.net/bugs/1791758 tty_ldisc_reinit() doesn't race with neither tty_ldisc_hangup() nor set_ldisc() nor tty_ldisc_release() as they use tty lock. But it races with anyone who expects line discipline to be the same after hoding read semaphore in tty_ldisc_ref(). We've seen the following crash on v4.9.108 stable: BUG: unable to handle kernel paging request at 0000000000002260 IP: [..] n_tty_receive_buf_common+0x5f/0x86d Workqueue: events_unbound flush_to_ldisc Call Trace: [..] n_tty_receive_buf2 [..] tty_ldisc_receive_buf [..] flush_to_ldisc [..] process_one_work [..] worker_thread [..] kthread [..] ret_from_fork tty_ldisc_reinit() should be called with ldisc_sem hold for writing, which will protect any reader against line discipline changes. Cc: Jiri Slaby Cc: stable@vger.kernel.org # b027e2298bd5 ("tty: fix data race between tty_init_dev and flush of buf") Reviewed-by: Jiri Slaby Reported-by: syzbot+3aa9784721dfb90e984d@syzkaller.appspotmail.com Tested-by: Mark Rutland Tested-by: Tetsuo Handa Signed-off-by: Dmitry Safonov Tested-by: Tycho Andersen Signed-off-by: Greg Kroah-Hartman (cherry-picked from 83d817f41070c48bc3eb7ec18e43000a548fca5c upstream) Signed-off-by: Guilherme G. Piccoli --- drivers/tty/tty_io.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index d2f00378fc18..3784f55f3dc9 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -1486,15 +1486,20 @@ static int tty_reopen(struct tty_struct *tty) if (test_bit(TTY_EXCLUSIVE, &tty->flags) && !capable(CAP_SYS_ADMIN)) return -EBUSY; - tty->count++; + retval = tty_ldisc_lock(tty, 5 * HZ); + if (retval) + return retval; + tty->count++; if (tty->ldisc) - return 0; + goto out_unlock; retval = tty_ldisc_reinit(tty, tty->termios.c_line); if (retval) tty->count--; +out_unlock: + tty_ldisc_unlock(tty); return retval; } From patchwork Tue Jan 8 20:18:48 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Guilherme G. Piccoli" X-Patchwork-Id: 1022123 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=canonical.com Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43Z3WM5nj3z9sN9; Wed, 9 Jan 2019 07:19:11 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1ggxq6-00087k-UK; Tue, 08 Jan 2019 20:19:06 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by huckleberry.canonical.com with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:128) (Exim 4.86_2) (envelope-from ) id 1ggxq5-00086p-PW for kernel-team@lists.ubuntu.com; Tue, 08 Jan 2019 20:19:05 +0000 Received: from mail-qk1-f198.google.com ([209.85.222.198]) by youngberry.canonical.com with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.76) (envelope-from ) id 1ggxq5-0007Vp-EL for kernel-team@lists.ubuntu.com; Tue, 08 Jan 2019 20:19:05 +0000 Received: by mail-qk1-f198.google.com with SMTP id a199so4123098qkb.23 for ; Tue, 08 Jan 2019 12:19:05 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=+M5d+c1uclx8/TMoVIN5vTD5iIix7eD2vjeS9Oz3/K4=; b=fZi8pJSDL1xaSG6ANStFNRDrq+JOcxcWQUfoYlAviG9Cg/Egm6s8w9ZxtFd/0+eh+K RYCpQgWb9CCt0H0Oh4iQR0kEFCZTiorpANH3dPnK9Gr94g/cjZE/iI4c7y95naPhPjC2 jyrdIK4EvwTeDYQEV57QKcg892GzZYPO6GcXwovop/yPEH3p8Ie2Nmv+NjVYQOBgzoZP m/bb0LaLbWgMO9bAzCiMffyaD6vPKDXmdCoHPjxwfBq2RmoNB7IA9RAnwU4HIacZxiGs dp1zu2TMo8RUBaUMFSRbtdo7wzblB2AQUq9ZDdx5sJy9YTjQDWuIj+ClrBdSd4BrPlR0 wCDw== X-Gm-Message-State: AJcUukdT6UXipqh0T5t0GooDNNJ0WLcegOH+fSNl83U0QediXMAt1Ccu rNwYNSDJCCqeSXo6b1/nq+J8uPDKo/bcm1AOShSychX1+UOf0i0HCM0Xh6ZqjczxFh1yISkIS6n nkNWxD31C0FxNKjlR1QoliDL5CjFHbhcO1jagahOzDA== X-Received: by 2002:a37:9d10:: with SMTP id g16mr2786192qke.53.1546978744343; Tue, 08 Jan 2019 12:19:04 -0800 (PST) X-Google-Smtp-Source: ALg8bN4uNou5JAxYJVuNL2MiNLte1cgDyDWpBHNvF1L53LJYljAAgdLcsC1CFCiECTsGLAHAKhyKCA== X-Received: by 2002:a37:9d10:: with SMTP id g16mr2786176qke.53.1546978744112; Tue, 08 Jan 2019 12:19:04 -0800 (PST) Received: from localhost ([191.13.50.232]) by smtp.gmail.com with ESMTPSA id 189sm30797755qkh.9.2019.01.08.12.19.03 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 08 Jan 2019 12:19:03 -0800 (PST) From: "Guilherme G. Piccoli" To: kernel-team@lists.ubuntu.com Subject: [SRU X] [PATCH 4/5] tty: Don't block on IO when ldisc change is pending Date: Tue, 8 Jan 2019 18:18:48 -0200 Message-Id: <20190108201849.11907-5-gpiccoli@canonical.com> X-Mailer: git-send-email 2.19.2 In-Reply-To: <20190108201849.11907-1-gpiccoli@canonical.com> References: <20190108201849.11907-1-gpiccoli@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: gpiccoli@canonical.com Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Dmitry Safonov BugLink: https://bugs.launchpad.net/bugs/1791758 There might be situations where tty_ldisc_lock() has blocked, but there is already IO on tty and it prevents line discipline changes. It might theoretically turn into dead-lock. Basically, provide more priority to pending tty_ldisc_lock() than to servicing reads/writes over tty. User-visible issue was reported by Mikulas where on pa-risc with Debian 5 reboot took either 80 seconds, 3 minutes or 3:25 after proper locking in tty_reopen(). Cc: Jiri Slaby Reported-by: Mikulas Patocka Signed-off-by: Dmitry Safonov Signed-off-by: Greg Kroah-Hartman (backported from c96cf923a98d1b094df9f0cf97a83e118817e31b upstream) [gpiccoli: context adjustment] Signed-off-by: Guilherme G. Piccoli --- drivers/tty/n_hdlc.c | 4 ++-- drivers/tty/n_r3964.c | 2 +- drivers/tty/n_tty.c | 8 ++++---- drivers/tty/tty_ldisc.c | 7 +++++++ include/linux/tty.h | 7 +++++++ 5 files changed, 21 insertions(+), 7 deletions(-) diff --git a/drivers/tty/n_hdlc.c b/drivers/tty/n_hdlc.c index 6d1e2f746ab4..401a650d7df1 100644 --- a/drivers/tty/n_hdlc.c +++ b/drivers/tty/n_hdlc.c @@ -613,7 +613,7 @@ static ssize_t n_hdlc_tty_read(struct tty_struct *tty, struct file *file, } /* no data */ - if (file->f_flags & O_NONBLOCK) { + if (tty_io_nonblock(tty, file)) { ret = -EAGAIN; break; } @@ -680,7 +680,7 @@ static ssize_t n_hdlc_tty_write(struct tty_struct *tty, struct file *file, if (tbuf) break; - if (file->f_flags & O_NONBLOCK) { + if (tty_io_nonblock(tty, file)) { error = -EAGAIN; break; } diff --git a/drivers/tty/n_r3964.c b/drivers/tty/n_r3964.c index 345111467b85..ee0e07b4a13d 100644 --- a/drivers/tty/n_r3964.c +++ b/drivers/tty/n_r3964.c @@ -1080,7 +1080,7 @@ static ssize_t r3964_read(struct tty_struct *tty, struct file *file, pMsg = remove_msg(pInfo, pClient); if (pMsg == NULL) { /* no messages available. */ - if (file->f_flags & O_NONBLOCK) { + if (tty_io_nonblock(tty, file)) { ret = -EAGAIN; goto unlock; } diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c index b1ec202099b2..940f6f171b89 100644 --- a/drivers/tty/n_tty.c +++ b/drivers/tty/n_tty.c @@ -1722,7 +1722,7 @@ n_tty_receive_buf_common(struct tty_struct *tty, const unsigned char *cp, down_read(&tty->termios_rwsem); - while (1) { + do { /* * When PARMRK is set, each input char may take up to 3 chars * in the read buf; reduce the buffer space avail by 3x @@ -1764,7 +1764,7 @@ n_tty_receive_buf_common(struct tty_struct *tty, const unsigned char *cp, fp += n; count -= n; rcvd += n; - } + } while (!test_bit(TTY_LDISC_CHANGING, &tty->flags)); tty->receive_room = room; @@ -2255,7 +2255,7 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file, break; if (!timeout) break; - if (file->f_flags & O_NONBLOCK) { + if (tty_io_nonblock(tty, file)) { retval = -EAGAIN; break; } @@ -2412,7 +2412,7 @@ static ssize_t n_tty_write(struct tty_struct *tty, struct file *file, } if (!nr) break; - if (file->f_flags & O_NONBLOCK) { + if (tty_io_nonblock(tty, file)) { retval = -EAGAIN; break; } diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c index fdc2c830a45c..bdae7db8ce76 100644 --- a/drivers/tty/tty_ldisc.c +++ b/drivers/tty/tty_ldisc.c @@ -330,6 +330,11 @@ tty_ldisc_lock(struct tty_struct *tty, unsigned long timeout) { int ret; + /* Kindly asking blocked readers to release the read side */ + set_bit(TTY_LDISC_CHANGING, &tty->flags); + wake_up_interruptible_all(&tty->read_wait); + wake_up_interruptible_all(&tty->write_wait); + ret = __tty_ldisc_lock(tty, timeout); if (!ret) return -EBUSY; @@ -340,6 +345,8 @@ tty_ldisc_lock(struct tty_struct *tty, unsigned long timeout) void tty_ldisc_unlock(struct tty_struct *tty) { clear_bit(TTY_LDISC_HALTED, &tty->flags); + /* Can be cleared here - ldisc_unlock will wake up writers firstly */ + clear_bit(TTY_LDISC_CHANGING, &tty->flags); __tty_ldisc_unlock(tty); } diff --git a/include/linux/tty.h b/include/linux/tty.h index 8927d8270620..ac687ab3320e 100644 --- a/include/linux/tty.h +++ b/include/linux/tty.h @@ -343,6 +343,7 @@ struct tty_file_private { #define TTY_NO_WRITE_SPLIT 17 /* Preserve write boundaries to driver */ #define TTY_HUPPED 18 /* Post driver->hangup() */ #define TTY_HUPPING 19 /* Hangup in progress */ +#define TTY_LDISC_CHANGING 20 /* Change pending - non-block IO */ #define TTY_LDISC_HALTED 22 /* Line discipline is halted */ #define TTY_WRITE_FLUSH(tty) tty_write_flush((tty)) @@ -362,6 +363,12 @@ static inline void tty_set_flow_change(struct tty_struct *tty, int val) smp_mb(); } +static inline bool tty_io_nonblock(struct tty_struct *tty, struct file *file) +{ + return file->f_flags & O_NONBLOCK || + test_bit(TTY_LDISC_CHANGING, &tty->flags); +} + #ifdef CONFIG_TTY extern void console_init(void); extern void tty_kref_put(struct tty_struct *tty); From patchwork Tue Jan 8 20:18:49 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Guilherme G. Piccoli" X-Patchwork-Id: 1022124 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=canonical.com Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 43Z3WR0yDVz9sDT; Wed, 9 Jan 2019 07:19:15 +1100 (AEDT) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1ggxqA-0008Ac-D9; Tue, 08 Jan 2019 20:19:10 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by huckleberry.canonical.com with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:128) (Exim 4.86_2) (envelope-from ) id 1ggxq8-00089U-OE for kernel-team@lists.ubuntu.com; Tue, 08 Jan 2019 20:19:08 +0000 Received: from mail-qt1-f200.google.com ([209.85.160.200]) by youngberry.canonical.com with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.76) (envelope-from ) id 1ggxq8-0007W2-Cp for kernel-team@lists.ubuntu.com; Tue, 08 Jan 2019 20:19:08 +0000 Received: by mail-qt1-f200.google.com with SMTP id q33so4433445qte.23 for ; Tue, 08 Jan 2019 12:19:08 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=ffmMCU1KCBzmnlF6X6PSQymDye13r/ObwNXg06AP3oY=; b=e1hYn82Cv3X+XtQhYpAXpHvF8Gb1M0LoiWzYcREBhrnWDTPycKe0P42x27EIbxs+r7 A5dxFY3xkj3D6gD9xmjH/c3fANH6YjQLRQ1nlehDnJnKXCM8WN9O6DtiNxiD8u4pE/X9 KU+ZPbA9Pmi6Q8/ia9xT0FAjho/x0wNwl8Y2mKKxHqalAmwwW4SKGIS0tHHkOTX5e8CT ZdAk1uAjE+QjYcLXF2ox0Jq1z4qNXvQLH2mq3qPGAj01aqTDlGmHHYB2EX4mjcUX+bHd k2LEHNcojumXz02pphq4XRqbuKKP2ttEW3kktJzD2wXOBnDmRKCfKQHsb3+58h+SkRJI 6pPw== X-Gm-Message-State: AJcUukd/L030CnWAHoc3xSJYzSw72A0zn1CBuxBBbzyt12MSKO4xaCiB rbn+rGmc7drZnetbsI842coFK3QmpynH5RIe448/Iwf/yaWzoSILNRVy5VELqyQaPFStVO5YNSq 2CtmvqAkwOFYEjNux/EAlHys23t5H5Gk7LiK+NOPOKg== X-Received: by 2002:ac8:16d8:: with SMTP id y24mr3085566qtk.253.1546978747170; Tue, 08 Jan 2019 12:19:07 -0800 (PST) X-Google-Smtp-Source: ALg8bN5Y5L69IrXeSYcDBAY2qQVLVsUf/PZGguz0+4GJrBoLFBFoS5hFNnL8VKzu98Rx5MHFIhMi/g== X-Received: by 2002:ac8:16d8:: with SMTP id y24mr3085544qtk.253.1546978746743; Tue, 08 Jan 2019 12:19:06 -0800 (PST) Received: from localhost ([191.13.50.232]) by smtp.gmail.com with ESMTPSA id g19sm7208513qke.2.2019.01.08.12.19.05 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 08 Jan 2019 12:19:06 -0800 (PST) From: "Guilherme G. Piccoli" To: kernel-team@lists.ubuntu.com Subject: [SRU X] [PATCH 5/5] tty: Simplify tty->count math in tty_reopen() Date: Tue, 8 Jan 2019 18:18:49 -0200 Message-Id: <20190108201849.11907-6-gpiccoli@canonical.com> X-Mailer: git-send-email 2.19.2 In-Reply-To: <20190108201849.11907-1-gpiccoli@canonical.com> References: <20190108201849.11907-1-gpiccoli@canonical.com> MIME-Version: 1.0 X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: gpiccoli@canonical.com Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Dmitry Safonov BugLink: https://bugs.launchpad.net/bugs/1791758 As notted by Jiri, tty_ldisc_reinit() shouldn't rely on tty counter. Simplify math by increasing the counter after reinit success. Cc: Jiri Slaby Link: lkml.kernel.org/r/<20180829022353.23568-2-dima@arista.com> Suggested-by: Jiri Slaby Reviewed-by: Jiri Slaby Tested-by: Mark Rutland Signed-off-by: Dmitry Safonov Signed-off-by: Greg Kroah-Hartman (cherry-picked from cf62a1a13749db0d32b5cdd800ea91a4087319de upstream) Signed-off-by: Guilherme G. Piccoli --- drivers/tty/tty_io.c | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c index 3784f55f3dc9..a7511d5fad9e 100644 --- a/drivers/tty/tty_io.c +++ b/drivers/tty/tty_io.c @@ -1490,16 +1490,13 @@ static int tty_reopen(struct tty_struct *tty) if (retval) return retval; - tty->count++; - if (tty->ldisc) - goto out_unlock; - - retval = tty_ldisc_reinit(tty, tty->termios.c_line); - if (retval) - tty->count--; - -out_unlock: + if (!tty->ldisc) + retval = tty_ldisc_reinit(tty, tty->termios.c_line); tty_ldisc_unlock(tty); + + if (retval == 0) + tty->count++; + return retval; }