Skip to content

Commit cb7a95a

Browse files
committed
hfs/hfsplus: avoid WARN_ON() for sanity check, use proper error handling
Commit 55d1cbb ("hfs/hfsplus: use WARN_ON for sanity check") fixed a build warning by turning a comment into a WARN_ON(), but it turns out that syzbot then complains because it can trigger said warning with a corrupted hfs image. The warning actually does warn about a bad situation, but we are much better off just handling it as the error it is. So rather than warn about us doing bad things, stop doing the bad things and return -EIO. While at it, also fix a memory leak that was introduced by an earlier fix for a similar syzbot warning situation, and add a check for one case that historically wasn't handled at all (ie neither comment nor subsequent WARN_ON). Reported-by: [email protected] Fixes: 55d1cbb ("hfs/hfsplus: use WARN_ON for sanity check") Fixes: 8d824e6 ("hfs: fix OOB Read in __hfs_brec_find") Link: https://lore.kernel.org/lkml/[email protected]/ Tested-by: Michael Schmitz <[email protected]> Cc: Arnd Bergmann <[email protected]> Cc: Matthew Wilcox <[email protected]> Cc: Viacheslav Dubeyko <[email protected]> Signed-off-by: Linus Torvalds <[email protected]>
1 parent a689b93 commit cb7a95a

File tree

1 file changed

+10
-5
lines changed

1 file changed

+10
-5
lines changed

fs/hfs/inode.c

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -458,15 +458,16 @@ int hfs_write_inode(struct inode *inode, struct writeback_control *wbc)
458458
/* panic? */
459459
return -EIO;
460460

461+
res = -EIO;
461462
if (HFS_I(main_inode)->cat_key.CName.len > HFS_NAMELEN)
462-
return -EIO;
463+
goto out;
463464
fd.search_key->cat = HFS_I(main_inode)->cat_key;
464465
if (hfs_brec_find(&fd))
465-
/* panic? */
466466
goto out;
467467

468468
if (S_ISDIR(main_inode->i_mode)) {
469-
WARN_ON(fd.entrylength < sizeof(struct hfs_cat_dir));
469+
if (fd.entrylength < sizeof(struct hfs_cat_dir))
470+
goto out;
470471
hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,
471472
sizeof(struct hfs_cat_dir));
472473
if (rec.type != HFS_CDR_DIR ||
@@ -479,14 +480,17 @@ int hfs_write_inode(struct inode *inode, struct writeback_control *wbc)
479480
hfs_bnode_write(fd.bnode, &rec, fd.entryoffset,
480481
sizeof(struct hfs_cat_dir));
481482
} else if (HFS_IS_RSRC(inode)) {
483+
if (fd.entrylength < sizeof(struct hfs_cat_file))
484+
goto out;
482485
hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,
483486
sizeof(struct hfs_cat_file));
484487
hfs_inode_write_fork(inode, rec.file.RExtRec,
485488
&rec.file.RLgLen, &rec.file.RPyLen);
486489
hfs_bnode_write(fd.bnode, &rec, fd.entryoffset,
487490
sizeof(struct hfs_cat_file));
488491
} else {
489-
WARN_ON(fd.entrylength < sizeof(struct hfs_cat_file));
492+
if (fd.entrylength < sizeof(struct hfs_cat_file))
493+
goto out;
490494
hfs_bnode_read(fd.bnode, &rec, fd.entryoffset,
491495
sizeof(struct hfs_cat_file));
492496
if (rec.type != HFS_CDR_FIL ||
@@ -503,9 +507,10 @@ int hfs_write_inode(struct inode *inode, struct writeback_control *wbc)
503507
hfs_bnode_write(fd.bnode, &rec, fd.entryoffset,
504508
sizeof(struct hfs_cat_file));
505509
}
510+
res = 0;
506511
out:
507512
hfs_find_exit(&fd);
508-
return 0;
513+
return res;
509514
}
510515

511516
static struct dentry *hfs_file_lookup(struct inode *dir, struct dentry *dentry,

0 commit comments

Comments
 (0)