Message ID | 20221022073521.1660841-3-zhangxiaoxu5@huawei.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Fix memory and page leak when writedata alloc failed | expand |
Good catch. Tentatively merged into cifs-2.6.git for-next pending testing. On Sat, Oct 22, 2022 at 1:32 AM Zhang Xiaoxu <zhangxiaoxu5@huawei.com> wrote: > > There is a memory leak when writedata alloc failed: > > unreferenced object 0xffff888192364000 (size 8192): > comm "sync", pid 22839, jiffies 4297313967 (age 60.230s) > hex dump (first 32 bytes): > 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ > 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ > backtrace: > [<0000000027de0814>] __kmalloc+0x4d/0x150 > [<00000000b21e81ab>] cifs_writepages+0x35f/0x14a0 > [<0000000076f7d20e>] do_writepages+0x10a/0x360 > [<00000000d6a36edc>] filemap_fdatawrite_wbc+0x95/0xc0 > [<000000005751a323>] __filemap_fdatawrite_range+0xa7/0xe0 > [<0000000088afb0ca>] file_write_and_wait_range+0x66/0xb0 > [<0000000063dbc443>] cifs_strict_fsync+0x80/0x5f0 > [<00000000c4624754>] __x64_sys_fsync+0x40/0x70 > [<000000002c0dc744>] do_syscall_64+0x35/0x80 > [<0000000052f46bee>] entry_SYSCALL_64_after_hwframe+0x46/0xb0 > > cifs_writepages+0x35f/0x14a0 is: > kmalloc_array at include/linux/slab.h:628 > (inlined by) kcalloc at include/linux/slab.h:659 > (inlined by) cifs_writedata_alloc at fs/cifs/file.c:2438 > (inlined by) wdata_alloc_and_fillpages at fs/cifs/file.c:2527 > (inlined by) cifs_writepages at fs/cifs/file.c:2705 > > If writedata alloc failed in cifs_writedata_alloc(), the pages array > should be freed. > > Fixes: 8e7360f67e75 ("CIFS: Add support for direct pages in wdata") > Signed-off-by: Zhang Xiaoxu <zhangxiaoxu5@huawei.com> > --- > fs/cifs/file.c | 10 +++++++--- > 1 file changed, 7 insertions(+), 3 deletions(-) > > diff --git a/fs/cifs/file.c b/fs/cifs/file.c > index 87be0223a57a..cd9698209930 100644 > --- a/fs/cifs/file.c > +++ b/fs/cifs/file.c > @@ -2434,12 +2434,16 @@ cifs_writev_complete(struct work_struct *work) > struct cifs_writedata * > cifs_writedata_alloc(unsigned int nr_pages, work_func_t complete) > { > + struct cifs_writedata *writedata = NULL; > struct page **pages = > kcalloc(nr_pages, sizeof(struct page *), GFP_NOFS); > - if (pages) > - return cifs_writedata_direct_alloc(pages, complete); > + if (pages) { > + writedata = cifs_writedata_direct_alloc(pages, complete); > + if (!writedata) > + kvfree(pages); > + } > > - return NULL; > + return writedata; > } > > struct cifs_writedata * > -- > 2.31.1 >
diff --git a/fs/cifs/file.c b/fs/cifs/file.c index 87be0223a57a..cd9698209930 100644 --- a/fs/cifs/file.c +++ b/fs/cifs/file.c @@ -2434,12 +2434,16 @@ cifs_writev_complete(struct work_struct *work) struct cifs_writedata * cifs_writedata_alloc(unsigned int nr_pages, work_func_t complete) { + struct cifs_writedata *writedata = NULL; struct page **pages = kcalloc(nr_pages, sizeof(struct page *), GFP_NOFS); - if (pages) - return cifs_writedata_direct_alloc(pages, complete); + if (pages) { + writedata = cifs_writedata_direct_alloc(pages, complete); + if (!writedata) + kvfree(pages); + } - return NULL; + return writedata; } struct cifs_writedata *
There is a memory leak when writedata alloc failed: unreferenced object 0xffff888192364000 (size 8192): comm "sync", pid 22839, jiffies 4297313967 (age 60.230s) hex dump (first 32 bytes): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ backtrace: [<0000000027de0814>] __kmalloc+0x4d/0x150 [<00000000b21e81ab>] cifs_writepages+0x35f/0x14a0 [<0000000076f7d20e>] do_writepages+0x10a/0x360 [<00000000d6a36edc>] filemap_fdatawrite_wbc+0x95/0xc0 [<000000005751a323>] __filemap_fdatawrite_range+0xa7/0xe0 [<0000000088afb0ca>] file_write_and_wait_range+0x66/0xb0 [<0000000063dbc443>] cifs_strict_fsync+0x80/0x5f0 [<00000000c4624754>] __x64_sys_fsync+0x40/0x70 [<000000002c0dc744>] do_syscall_64+0x35/0x80 [<0000000052f46bee>] entry_SYSCALL_64_after_hwframe+0x46/0xb0 cifs_writepages+0x35f/0x14a0 is: kmalloc_array at include/linux/slab.h:628 (inlined by) kcalloc at include/linux/slab.h:659 (inlined by) cifs_writedata_alloc at fs/cifs/file.c:2438 (inlined by) wdata_alloc_and_fillpages at fs/cifs/file.c:2527 (inlined by) cifs_writepages at fs/cifs/file.c:2705 If writedata alloc failed in cifs_writedata_alloc(), the pages array should be freed. Fixes: 8e7360f67e75 ("CIFS: Add support for direct pages in wdata") Signed-off-by: Zhang Xiaoxu <zhangxiaoxu5@huawei.com> --- fs/cifs/file.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)