Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a75d9211 authored by Tetsuo Handa's avatar Tetsuo Handa Committed by Greg Kroah-Hartman
Browse files

fs: hfsplus: remove WARN_ON() from hfsplus_cat_{read,write}_inode()



[ Upstream commit 81b21c0f0138ff5a499eafc3eb0578ad2a99622c ]

syzbot is hitting WARN_ON() in hfsplus_cat_{read,write}_inode(), for
crafted filesystem image can contain bogus length. There conditions are
not kernel bugs that can justify kernel to panic.

Reported-by: default avatarsyzbot <syzbot+e2787430e752a92b8750@syzkaller.appspotmail.com>
Link: https://syzkaller.appspot.com/bug?extid=e2787430e752a92b8750


Reported-by: default avatarsyzbot <syzbot+4913dca2ea6e4d43f3f1@syzkaller.appspotmail.com>
Link: https://syzkaller.appspot.com/bug?extid=4913dca2ea6e4d43f3f1


Signed-off-by: default avatarTetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Reviewed-by: default avatarViacheslav Dubeyko <slava@dubeyko.com>
Message-Id: <15308173-5252-d6a3-ae3b-e96d46cb6f41@I-love.SAKURA.ne.jp>
Signed-off-by: default avatarChristian Brauner <brauner@kernel.org>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent 196528ad
Loading
Loading
Loading
Loading
+23 −5
Original line number Diff line number Diff line
@@ -497,7 +497,11 @@ int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd)
	if (type == HFSPLUS_FOLDER) {
		struct hfsplus_cat_folder *folder = &entry.folder;

		WARN_ON(fd->entrylength < sizeof(struct hfsplus_cat_folder));
		if (fd->entrylength < sizeof(struct hfsplus_cat_folder)) {
			pr_err("bad catalog folder entry\n");
			res = -EIO;
			goto out;
		}
		hfs_bnode_read(fd->bnode, &entry, fd->entryoffset,
					sizeof(struct hfsplus_cat_folder));
		hfsplus_get_perms(inode, &folder->permissions, 1);
@@ -517,7 +521,11 @@ int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd)
	} else if (type == HFSPLUS_FILE) {
		struct hfsplus_cat_file *file = &entry.file;

		WARN_ON(fd->entrylength < sizeof(struct hfsplus_cat_file));
		if (fd->entrylength < sizeof(struct hfsplus_cat_file)) {
			pr_err("bad catalog file entry\n");
			res = -EIO;
			goto out;
		}
		hfs_bnode_read(fd->bnode, &entry, fd->entryoffset,
					sizeof(struct hfsplus_cat_file));

@@ -548,6 +556,7 @@ int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd)
		pr_err("bad catalog entry used to create inode\n");
		res = -EIO;
	}
out:
	return res;
}

@@ -556,6 +565,7 @@ int hfsplus_cat_write_inode(struct inode *inode)
	struct inode *main_inode = inode;
	struct hfs_find_data fd;
	hfsplus_cat_entry entry;
	int res = 0;

	if (HFSPLUS_IS_RSRC(inode))
		main_inode = HFSPLUS_I(inode)->rsrc_inode;
@@ -574,7 +584,11 @@ int hfsplus_cat_write_inode(struct inode *inode)
	if (S_ISDIR(main_inode->i_mode)) {
		struct hfsplus_cat_folder *folder = &entry.folder;

		WARN_ON(fd.entrylength < sizeof(struct hfsplus_cat_folder));
		if (fd.entrylength < sizeof(struct hfsplus_cat_folder)) {
			pr_err("bad catalog folder entry\n");
			res = -EIO;
			goto out;
		}
		hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
					sizeof(struct hfsplus_cat_folder));
		/* simple node checks? */
@@ -599,7 +613,11 @@ int hfsplus_cat_write_inode(struct inode *inode)
	} else {
		struct hfsplus_cat_file *file = &entry.file;

		WARN_ON(fd.entrylength < sizeof(struct hfsplus_cat_file));
		if (fd.entrylength < sizeof(struct hfsplus_cat_file)) {
			pr_err("bad catalog file entry\n");
			res = -EIO;
			goto out;
		}
		hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
					sizeof(struct hfsplus_cat_file));
		hfsplus_inode_write_fork(inode, &file->data_fork);
@@ -620,5 +638,5 @@ int hfsplus_cat_write_inode(struct inode *inode)
	set_bit(HFSPLUS_I_CAT_DIRTY, &HFSPLUS_I(inode)->flags);
out:
	hfs_find_exit(&fd);
	return 0;
	return res;
}