lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite for Android: free password hash cracker in your pocket
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <01a93294-e323-b9ca-7e95-a33d4b89dc47@I-love.SAKURA.ne.jp>
Date:   Mon, 4 Jul 2022 21:34:04 +0900
From:   Tetsuo Handa <penguin-kernel@...ove.SAKURA.ne.jp>
To:     Greg KH <gregkh@...uxfoundation.org>,
        "Rafael J. Wysocki" <rafael@...nel.org>,
        Len Brown <len.brown@...el.com>, Pavel Machek <pavel@....cz>
Cc:     arnd@...db.de, linux-kernel@...r.kernel.org,
        linux-pm@...r.kernel.org
Subject: Re: [PATCH] char: misc: make misc_open() and misc_register() killable

On 2022/07/04 20:01, Greg KH wrote:
> On Mon, Jul 04, 2022 at 07:25:44PM +0900, Tetsuo Handa wrote:
>> On 2022/07/04 16:29, Greg KH wrote:
>>> On Mon, Jul 04, 2022 at 03:44:07PM +0900, Tetsuo Handa wrote:
>>>> syzbot is reporting hung task at misc_open() [1], for snapshot_open() from
>>>> misc_open() might sleep for long with misc_mtx held whereas userspace can
>>>> flood with concurrent misc_open() requests. Mitigate this problem by making
>>>> misc_open() and misc_register() killable.
>>>
>>> I do not understand, why not just fix snapshot_open()?  Why add this
>>> complexity to the misc core for a foolish individual misc device?  Why
>>> not add the fix there where it is spinning instead?
>>
>> Quoting an example from [1]. Multiple processes are calling misc_open() and
>> all but one processes are blocked at mutex_lock(&misc_mtx). The one which is
>> not blocked at mutex_lock(&misc_mtx) is also holding system_transition_mutex.
> 
> And that is because of that one misc device, right?  Why not fix that
> instead of papering over the issue in the misc core?

Since "struct file_operations"->open() is allowed to sleep, calling
"struct file_operations"->open() via reassignment by "struct miscdevice"->fops
with locks held can cause problems.

Assuming that this is not a deadlock hidden by device_initialize(), current
mutex_lock(&misc_mtx) is as problematic as major_names_lock mentioned at
https://lkml.kernel.org/r/b2af8a5b-3c1b-204e-7f56-bea0b15848d6@i-love.sakura.ne.jp .

>> If you don't like mutex_lock_killable(&misc_mtx), we will need to consider moving
>> file->f_op->open() from misc_open() to after mutex_unlock(&misc_mtx).

Below is minimal changes for avoid calling "struct file_operations"->open() with
misc_mtx held. This would be nothing but moving hung task warning from misc_open()
to snapshot_open() (and therefore we would need to introduce killable version of
lock_system_sleep()), but we can avoid making misc_mtx like major_names_lock above.

Greg, can you accept this minimal change?

 drivers/char/misc.c        | 4 ++++
 include/linux/miscdevice.h | 1 +
 kernel/power/user.c        | 1 +
 3 files changed, 6 insertions(+)

diff --git a/drivers/char/misc.c b/drivers/char/misc.c
index cba19bfdc44d..292c86c090b9 100644
--- a/drivers/char/misc.c
+++ b/drivers/char/misc.c
@@ -139,6 +139,10 @@ static int misc_open(struct inode *inode, struct file *file)
 
 	err = 0;
 	replace_fops(file, new_fops);
+	if (iter->unlocked_open && file->f_op->open) {
+		mutex_unlock(&misc_mtx);
+		return file->f_op->open(inode, file);
+	}
 	if (file->f_op->open)
 		err = file->f_op->open(inode, file);
 fail:
diff --git a/include/linux/miscdevice.h b/include/linux/miscdevice.h
index 0676f18093f9..e112ef9e3b7b 100644
--- a/include/linux/miscdevice.h
+++ b/include/linux/miscdevice.h
@@ -86,6 +86,7 @@ struct miscdevice  {
 	const struct attribute_group **groups;
 	const char *nodename;
 	umode_t mode;
+	bool unlocked_open;
 };
 
 extern int misc_register(struct miscdevice *misc);
diff --git a/kernel/power/user.c b/kernel/power/user.c
index ad241b4ff64c..69a269c4fb46 100644
--- a/kernel/power/user.c
+++ b/kernel/power/user.c
@@ -441,6 +441,7 @@ static struct miscdevice snapshot_device = {
 	.minor = SNAPSHOT_MINOR,
 	.name = "snapshot",
 	.fops = &snapshot_fops,
+	.unlocked_open = true,
 };
 
 static int __init snapshot_device_init(void)
-- 
2.34.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ