From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754759AbdLLNWn (ORCPT ); Tue, 12 Dec 2017 08:22:43 -0500 Received: from mail-pg0-f68.google.com ([74.125.83.68]:45179 "EHLO mail-pg0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751728AbdLLNWl (ORCPT ); Tue, 12 Dec 2017 08:22:41 -0500 X-Google-Smtp-Source: ACJfBotkQikrvMU6crTr61Z99A1usnRqHpqeFcDUJQUk+IrbAYxx+U6lFnMR0Q2qsxc14LTsRcbASQ== From: Jia-Ju Bai To: gregkh@linuxfoundation.org, jslaby@suse.com, acme@conectiva.com.br Cc: linux-kernel@vger.kernel.org, Jia-Ju Bai Subject: [PATCH] tty/isicom: Fix a possible sleep-in-atomic bug in WaitTillCardIsFree Date: Tue, 12 Dec 2017 21:24:56 +0800 Message-Id: <1513085096-28422-1-git-send-email-baijiaju1990@gmail.com> X-Mailer: git-send-email 1.7.9.5 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The driver may sleep under a spinlock. The function call paths are: isicom_activate (acquire the spinlock) isicom_setup_board drop_dtr_rts WaitTillCardIsFree msleep --> may sleep isicom_set_termios isicom_config_port drop_dtr WaitTillCardIsFree msleep --> may sleep isicom_tiocmset drop_dtr WaitTillCardIsFree msleep --> may sleep Though "in_atomic" is used to check atomic context, but it is not recommended to use in driver code (see include/linux/preempt.h). To fix it, only using mdelay instead. This bug is found by my static analysis tool(DSAC) and checked by my code review. Signed-off-by: Jia-Ju Bai --- drivers/tty/isicom.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/tty/isicom.c b/drivers/tty/isicom.c index 015686f..bdd3027 100644 --- a/drivers/tty/isicom.c +++ b/drivers/tty/isicom.c @@ -219,13 +219,9 @@ struct isi_port { static int WaitTillCardIsFree(unsigned long base) { unsigned int count = 0; - unsigned int a = in_atomic(); /* do we run under spinlock? */ while (!(inw(base + 0xe) & 0x1) && count++ < 100) - if (a) - mdelay(1); - else - msleep(1); + mdelay(1); return !(inw(base + 0xe) & 0x1); } -- 1.7.9.5