From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751997AbdJFMTp (ORCPT ); Fri, 6 Oct 2017 08:19:45 -0400 Received: from zeniv.linux.org.uk ([195.92.253.2]:49412 "EHLO ZenIV.linux.org.uk" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751663AbdJFMTn (ORCPT ); Fri, 6 Oct 2017 08:19:43 -0400 Date: Fri, 6 Oct 2017 13:19:30 +0100 From: Al Viro To: Jia-Ju Bai Cc: torbjorn.lindh@gopta.se, rgooch@atnf.csiro.au, linux-fsdevel@vger.kernel.org, linux-kernel@vger.kernel.org Subject: Re: [BUG] fs/super: a possible sleep-in-atomic bug in put_super Message-ID: <20171006121930.GL21978@ZenIV.linux.org.uk> References: <06badf5e-292d-ef63-7499-6888dec1b9b0@163.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <06badf5e-292d-ef63-7499-6888dec1b9b0@163.com> User-Agent: Mutt/1.9.0 (2017-09-02) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Fri, Oct 06, 2017 at 04:59:18PM +0800, Jia-Ju Bai wrote: > According to fs/super.c, the kernel may sleep under a spinlock. > The function call path is: > put_super (acquire the spinlock) > __put_super > destroy_super > list_lru_destroy > list_lru_unregister > mutex_lock --> may sleep > memcg_get_cache_ids > down_read --> may sleep > > This bug is found by my static analysis tool and my code review. Invariant to watch is this: s->s_active > 0 => s->s_count > 0. In other words, anything that passes from __put_super() to destroy_super() has already been through deactivate_locked_super() to list_lru_destroy(). And list_lru_destroy() called twice without list_lru_init() between those will quietly do nothing on the second call. All other callers of destroy_super() are from alloc_super()/sget_userns(). The former is the only place where instances are created, the latter is the only caller of the former. Direct calls of destroy_super() in there a) happen only to instances that had not been visible in any shared data structures yet and b) are done with no spinlocks held. struct super_block has probably the most complex lifecycle in the entire VFS. These days the nastiness is fortunately limited to fs/super.c guts, but it's very definitely still there. I've posted sketches of description on fsdevel several times, but never managed to turn that into coherent text ;-/