Skip to content

Commit 05ce49a

Browse files
Mehdibenhadjkhelifadubeyko
authored andcommitted
hfs: ensure sb->s_fs_info is always cleaned up
When hfs was converted to the new mount api a bug was introduced by changing the allocation pattern of sb->s_fs_info. If setup_bdev_super() fails after a new superblock has been allocated by sget_fc(), but before hfs_fill_super() takes ownership of the filesystem-specific s_fs_info data it was leaked. Fix this by freeing sb->s_fs_info in hfs_kill_super(). Cc: stable@vger.kernel.org Fixes: ffcd06b ("hfs: convert hfs to use the new mount api") Reported-by: syzbot+ad45f827c88778ff7df6@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=ad45f827c88778ff7df6 Tested-by: Viacheslav Dubeyko <Slava.Dubeyko@ibm.com> Signed-off-by: Christian Brauner <brauner@kernel.org> Signed-off-by: Mehdi Ben Hadj Khelifa <mehdi.benhadjkhelifa@gmail.com> Reviewed-by: Viacheslav Dubeyko <slava@dubeyko.com> Signed-off-by: Viacheslav Dubeyko <slava@dubeyko.com> Link: https://lore.kernel.org/r/20251201222843.82310-2-mehdi.benhadjkhelifa@gmail.com Signed-off-by: Viacheslav Dubeyko <slava@dubeyko.com>
1 parent 8f0b4cc commit 05ce49a

2 files changed

Lines changed: 23 additions & 22 deletions

File tree

fs/hfs/mdb.c

Lines changed: 14 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ int hfs_mdb_get(struct super_block *sb)
9292
/* See if this is an HFS filesystem */
9393
bh = sb_bread512(sb, part_start + HFS_MDB_BLK, mdb);
9494
if (!bh)
95-
goto out;
95+
return -EIO;
9696

9797
if (mdb->drSigWord == cpu_to_be16(HFS_SUPER_MAGIC))
9898
break;
@@ -102,13 +102,14 @@ int hfs_mdb_get(struct super_block *sb)
102102
* (should do this only for cdrom/loop though)
103103
*/
104104
if (hfs_part_find(sb, &part_start, &part_size))
105-
goto out;
105+
return -EIO;
106106
}
107107

108108
HFS_SB(sb)->alloc_blksz = size = be32_to_cpu(mdb->drAlBlkSiz);
109109
if (!size || (size & (HFS_SECTOR_SIZE - 1))) {
110110
pr_err("bad allocation block size %d\n", size);
111-
goto out_bh;
111+
brelse(bh);
112+
return -EIO;
112113
}
113114

114115
size = min(HFS_SB(sb)->alloc_blksz, (u32)PAGE_SIZE);
@@ -125,14 +126,16 @@ int hfs_mdb_get(struct super_block *sb)
125126
brelse(bh);
126127
if (!sb_set_blocksize(sb, size)) {
127128
pr_err("unable to set blocksize to %u\n", size);
128-
goto out;
129+
return -EIO;
129130
}
130131

131132
bh = sb_bread512(sb, part_start + HFS_MDB_BLK, mdb);
132133
if (!bh)
133-
goto out;
134-
if (mdb->drSigWord != cpu_to_be16(HFS_SUPER_MAGIC))
135-
goto out_bh;
134+
return -EIO;
135+
if (mdb->drSigWord != cpu_to_be16(HFS_SUPER_MAGIC)) {
136+
brelse(bh);
137+
return -EIO;
138+
}
136139

137140
HFS_SB(sb)->mdb_bh = bh;
138141
HFS_SB(sb)->mdb = mdb;
@@ -174,7 +177,7 @@ int hfs_mdb_get(struct super_block *sb)
174177

175178
HFS_SB(sb)->bitmap = kzalloc(8192, GFP_KERNEL);
176179
if (!HFS_SB(sb)->bitmap)
177-
goto out;
180+
return -EIO;
178181

179182
/* read in the bitmap */
180183
block = be16_to_cpu(mdb->drVBMSt) + part_start;
@@ -185,7 +188,7 @@ int hfs_mdb_get(struct super_block *sb)
185188
bh = sb_bread(sb, off >> sb->s_blocksize_bits);
186189
if (!bh) {
187190
pr_err("unable to read volume bitmap\n");
188-
goto out;
191+
return -EIO;
189192
}
190193
off2 = off & (sb->s_blocksize - 1);
191194
len = min((int)sb->s_blocksize - off2, size);
@@ -199,12 +202,12 @@ int hfs_mdb_get(struct super_block *sb)
199202
HFS_SB(sb)->ext_tree = hfs_btree_open(sb, HFS_EXT_CNID, hfs_ext_keycmp);
200203
if (!HFS_SB(sb)->ext_tree) {
201204
pr_err("unable to open extent tree\n");
202-
goto out;
205+
return -EIO;
203206
}
204207
HFS_SB(sb)->cat_tree = hfs_btree_open(sb, HFS_CAT_CNID, hfs_cat_keycmp);
205208
if (!HFS_SB(sb)->cat_tree) {
206209
pr_err("unable to open catalog tree\n");
207-
goto out;
210+
return -EIO;
208211
}
209212

210213
attrib = mdb->drAtrb;
@@ -229,12 +232,6 @@ int hfs_mdb_get(struct super_block *sb)
229232
}
230233

231234
return 0;
232-
233-
out_bh:
234-
brelse(bh);
235-
out:
236-
hfs_mdb_put(sb);
237-
return -EIO;
238235
}
239236

240237
/*
@@ -359,8 +356,6 @@ void hfs_mdb_close(struct super_block *sb)
359356
* Release the resources associated with the in-core MDB. */
360357
void hfs_mdb_put(struct super_block *sb)
361358
{
362-
if (!HFS_SB(sb))
363-
return;
364359
/* free the B-trees */
365360
hfs_btree_close(HFS_SB(sb)->ext_tree);
366361
hfs_btree_close(HFS_SB(sb)->cat_tree);
@@ -373,6 +368,4 @@ void hfs_mdb_put(struct super_block *sb)
373368
unload_nls(HFS_SB(sb)->nls_disk);
374369

375370
kfree(HFS_SB(sb)->bitmap);
376-
kfree(HFS_SB(sb));
377-
sb->s_fs_info = NULL;
378371
}

fs/hfs/super.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -431,10 +431,18 @@ static int hfs_init_fs_context(struct fs_context *fc)
431431
return 0;
432432
}
433433

434+
static void hfs_kill_super(struct super_block *sb)
435+
{
436+
struct hfs_sb_info *hsb = HFS_SB(sb);
437+
438+
kill_block_super(sb);
439+
kfree(hsb);
440+
}
441+
434442
static struct file_system_type hfs_fs_type = {
435443
.owner = THIS_MODULE,
436444
.name = "hfs",
437-
.kill_sb = kill_block_super,
445+
.kill_sb = hfs_kill_super,
438446
.fs_flags = FS_REQUIRES_DEV,
439447
.init_fs_context = hfs_init_fs_context,
440448
};

0 commit comments

Comments
 (0)