• Yuan Can's avatar
    floppy: Fix memory leak in do_floppy_init() · f8ace2e3
    Yuan Can authored
    A memory leak was reported when floppy_alloc_disk() failed in
    do_floppy_init().
    
    unreferenced object 0xffff888115ed25a0 (size 8):
      comm "modprobe", pid 727, jiffies 4295051278 (age 25.529s)
      hex dump (first 8 bytes):
        00 ac 67 5b 81 88 ff ff                          ..g[....
      backtrace:
        [<000000007f457abb>] __kmalloc_node+0x4c/0xc0
        [<00000000a87bfa9e>] blk_mq_realloc_tag_set_tags.part.0+0x6f/0x180
        [<000000006f02e8b1>] blk_mq_alloc_tag_set+0x573/0x1130
        [<0000000066007fd7>] 0xffffffffc06b8b08
        [<0000000081f5ac40>] do_one_initcall+0xd0/0x4f0
        [<00000000e26d04ee>] do_init_module+0x1a4/0x680
        [<000000001bb22407>] load_module+0x6249/0x7110
        [<00000000ad31ac4d>] __do_sys_finit_module+0x140/0x200
        [<000000007bddca46>] do_syscall_64+0x35/0x80
        [<00000000b5afec39>] entry_SYSCALL_64_after_hwframe+0x46/0xb0
    unreferenced object 0xffff88810fc30540 (size 32):
      comm "modprobe", pid 727, jiffies 4295051278 (age 25.529s)
      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:
        [<000000007f457abb>] __kmalloc_node+0x4c/0xc0
        [<000000006b91eab4>] blk_mq_alloc_tag_set+0x393/0x1130
        [<0000000066007fd7>] 0xffffffffc06b8b08
        [<0000000081f5ac40>] do_one_initcall+0xd0/0x4f0
        [<00000000e26d04ee>] do_init_module+0x1a4/0x680
        [<000000001bb22407>] load_module+0x6249/0x7110
        [<00000000ad31ac4d>] __do_sys_finit_module+0x140/0x200
        [<000000007bddca46>] do_syscall_64+0x35/0x80
        [<00000000b5afec39>] entry_SYSCALL_64_after_hwframe+0x46/0xb0
    
    If the floppy_alloc_disk() failed, disks of current drive will not be set,
    thus the lastest allocated set->tag cannot be freed in the error handling
    path. A simple call graph shown as below:
    
     floppy_module_init()
       floppy_init()
         do_floppy_init()
           for (drive = 0; drive < N_DRIVE; drive++)
             blk_mq_alloc_tag_set()
               blk_mq_alloc_tag_set_tags()
                 blk_mq_realloc_tag_set_tags() # set->tag allocated
             floppy_alloc_disk()
               blk_mq_alloc_disk() # error occurred, disks failed to allocated
    
           ->out_put_disk:
           for (drive = 0; drive < N_DRIVE; drive++)
             if (!disks[drive][0]) # the last disks is not set and loop break
               break;
             blk_mq_free_tag_set() # the latest allocated set->tag leaked
    
    Fix this problem by free the set->tag of current drive before jump to
    error handling path.
    
    Cc: stable@vger.kernel.org
    Fixes: 302cfee1 ("floppy: use a separate gendisk for each media format")
    Signed-off-by: default avatarYuan Can <yuancan@huawei.com>
    [efremov: added stable list, changed title]
    Signed-off-by: default avatarDenis Efremov <efremov@linux.com>
    f8ace2e3
floppy.c 134 KB