1 |
From f8ace2e304c5dd8a7328db9cd2b8a4b1b98d83ec Mon Sep 17 00:00:00 2001 |
2 |
From: Yuan Can <yuancan@huawei.com> |
3 |
Date: Mon, 31 Oct 2022 12:04:43 +0000 |
4 |
Subject: [PATCH] floppy: Fix memory leak in do_floppy_init() |
5 |
|
6 |
A memory leak was reported when floppy_alloc_disk() failed in |
7 |
do_floppy_init(). |
8 |
|
9 |
unreferenced object 0xffff888115ed25a0 (size 8): |
10 |
comm "modprobe", pid 727, jiffies 4295051278 (age 25.529s) |
11 |
hex dump (first 8 bytes): |
12 |
00 ac 67 5b 81 88 ff ff ..g[.... |
13 |
backtrace: |
14 |
[<000000007f457abb>] __kmalloc_node+0x4c/0xc0 |
15 |
[<00000000a87bfa9e>] blk_mq_realloc_tag_set_tags.part.0+0x6f/0x180 |
16 |
[<000000006f02e8b1>] blk_mq_alloc_tag_set+0x573/0x1130 |
17 |
[<0000000066007fd7>] 0xffffffffc06b8b08 |
18 |
[<0000000081f5ac40>] do_one_initcall+0xd0/0x4f0 |
19 |
[<00000000e26d04ee>] do_init_module+0x1a4/0x680 |
20 |
[<000000001bb22407>] load_module+0x6249/0x7110 |
21 |
[<00000000ad31ac4d>] __do_sys_finit_module+0x140/0x200 |
22 |
[<000000007bddca46>] do_syscall_64+0x35/0x80 |
23 |
[<00000000b5afec39>] entry_SYSCALL_64_after_hwframe+0x46/0xb0 |
24 |
unreferenced object 0xffff88810fc30540 (size 32): |
25 |
comm "modprobe", pid 727, jiffies 4295051278 (age 25.529s) |
26 |
hex dump (first 32 bytes): |
27 |
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ |
28 |
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ |
29 |
backtrace: |
30 |
[<000000007f457abb>] __kmalloc_node+0x4c/0xc0 |
31 |
[<000000006b91eab4>] blk_mq_alloc_tag_set+0x393/0x1130 |
32 |
[<0000000066007fd7>] 0xffffffffc06b8b08 |
33 |
[<0000000081f5ac40>] do_one_initcall+0xd0/0x4f0 |
34 |
[<00000000e26d04ee>] do_init_module+0x1a4/0x680 |
35 |
[<000000001bb22407>] load_module+0x6249/0x7110 |
36 |
[<00000000ad31ac4d>] __do_sys_finit_module+0x140/0x200 |
37 |
[<000000007bddca46>] do_syscall_64+0x35/0x80 |
38 |
[<00000000b5afec39>] entry_SYSCALL_64_after_hwframe+0x46/0xb0 |
39 |
|
40 |
If the floppy_alloc_disk() failed, disks of current drive will not be set, |
41 |
thus the lastest allocated set->tag cannot be freed in the error handling |
42 |
path. A simple call graph shown as below: |
43 |
|
44 |
floppy_module_init() |
45 |
floppy_init() |
46 |
do_floppy_init() |
47 |
for (drive = 0; drive < N_DRIVE; drive++) |
48 |
blk_mq_alloc_tag_set() |
49 |
blk_mq_alloc_tag_set_tags() |
50 |
blk_mq_realloc_tag_set_tags() # set->tag allocated |
51 |
floppy_alloc_disk() |
52 |
blk_mq_alloc_disk() # error occurred, disks failed to allocated |
53 |
|
54 |
->out_put_disk: |
55 |
for (drive = 0; drive < N_DRIVE; drive++) |
56 |
if (!disks[drive][0]) # the last disks is not set and loop break |
57 |
break; |
58 |
blk_mq_free_tag_set() # the latest allocated set->tag leaked |
59 |
|
60 |
Fix this problem by free the set->tag of current drive before jump to |
61 |
error handling path. |
62 |
|
63 |
Cc: stable@vger.kernel.org |
64 |
Fixes: 302cfee15029 ("floppy: use a separate gendisk for each media format") |
65 |
Signed-off-by: Yuan Can <yuancan@huawei.com> |
66 |
[efremov: added stable list, changed title] |
67 |
Signed-off-by: Denis Efremov <efremov@linux.com> |
68 |
--- |
69 |
drivers/block/floppy.c | 4 +++- |
70 |
1 file changed, 3 insertions(+), 1 deletion(-) |
71 |
|
72 |
diff --git a/drivers/block/floppy.c b/drivers/block/floppy.c |
73 |
index ccad3d7b3ddd9a..487840e3564dff 100644 |
74 |
--- a/drivers/block/floppy.c |
75 |
+++ b/drivers/block/floppy.c |
76 |
@@ -4593,8 +4593,10 @@ static int __init do_floppy_init(void) |
77 |
goto out_put_disk; |
78 |
|
79 |
err = floppy_alloc_disk(drive, 0); |
80 |
- if (err) |
81 |
+ if (err) { |
82 |
+ blk_mq_free_tag_set(&tag_sets[drive]); |
83 |
goto out_put_disk; |
84 |
+ } |
85 |
|
86 |
timer_setup(&motor_off_timer[drive], motor_off_callback, 0); |
87 |
} |