Message ID | 20191217135143.12875-1-baijiaju1990@gmail.com |
---|---|
State | New |
Delegated to: | David Woodhouse |
Headers | show |
Series | fs: jffs2: fix possible sleep-in-atomic-context bugs | expand |
On Tue, Dec 17, 2019 at 09:51:43PM +0800, Jia-Ju Bai wrote: > The filesystem may sleep while holding a spinlock. > The function call path (from bottom to top) in Linux 4.19 is: > > fs/jffs2/malloc.c, 188: > kmem_cache_alloc(GFP_KERNEL) in jffs2_alloc_refblock > fs/jffs2/malloc.c, 221: > jffs2_alloc_refblock in jffs2_prealloc_raw_node_refs ... gets called only if jeb->last_node is NULL. I've no idea whether it is possible on those call chains and analysis is certainly needed before applying that kind of patches. It might very well be real, and certainly worth asking jffs2 folks to look into. But this kind of "defensive" fixes is no good without understanding of the situation in the code being (hopefully) fixed. It's a good catch; even if there is a reason why we never hit the blocking allocation in there, that reason should be spelled out in the code. It isn't, and that can easily grow into a bug even if it hasn't done so already.
diff --git a/fs/jffs2/malloc.c b/fs/jffs2/malloc.c index ce1189793288..66496ef09716 100644 --- a/fs/jffs2/malloc.c +++ b/fs/jffs2/malloc.c @@ -185,7 +185,7 @@ static struct jffs2_raw_node_ref *jffs2_alloc_refblock(void) { struct jffs2_raw_node_ref *ret; - ret = kmem_cache_alloc(raw_node_ref_slab, GFP_KERNEL); + ret = kmem_cache_alloc(raw_node_ref_slab, GFP_ATOMIC); if (ret) { int i = 0; for (i=0; i < REFS_PER_BLOCK; i++) {
The filesystem may sleep while holding a spinlock. The function call path (from bottom to top) in Linux 4.19 is: fs/jffs2/malloc.c, 188: kmem_cache_alloc(GFP_KERNEL) in jffs2_alloc_refblock fs/jffs2/malloc.c, 221: jffs2_alloc_refblock in jffs2_prealloc_raw_node_refs fs/jffs2/wbuf.c, 164: jffs2_prealloc_raw_node_refs in jffs2_block_refile fs/jffs2/wbuf.c, 291: jffs2_block_refile in jffs2_wbuf_recover fs/jffs2/wbuf.c, 287: spin_lock in jffs2_wbuf_recover fs/jffs2/malloc.c, 188: kmem_cache_alloc(GFP_KERNEL) in jffs2_alloc_refblock fs/jffs2/malloc.c, 221: jffs2_alloc_refblock in jffs2_prealloc_raw_node_refs fs/jffs2/wbuf.c, 164: jffs2_prealloc_raw_node_refs in jffs2_block_refile fs/jffs2/wbuf.c, 927: jffs2_block_refile in jffs2_flash_writev fs/jffs2/wbuf.c, 924: spin_lock in jffs2_flash_writev kmem_cache_alloc(GFP_KERNEL) can sleep at runtime. To fix these possible bugs, GFP_KERNEL is replaced with GFP_ATOMIC for kmem_cache_alloc(). These bugs are found by a static analysis tool STCheck written by myself. Signed-off-by: Jia-Ju Bai <baijiaju1990@gmail.com> --- fs/jffs2/malloc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)