Re: [PATCH 2/2] cifs: Fix pages array leak when writedata alloc failed in cifs_writedata_alloc()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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@xxxxxxxxxx> 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@xxxxxxxxxx>
> ---
>  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
>


-- 
Thanks,

Steve



[Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux