Commit 81b21c0f authored by Tetsuo Handa's avatar Tetsuo Handa Committed by Christian Brauner

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

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=e2787430e752a92b8750Reported-by: default avatarsyzbot <syzbot+4913dca2ea6e4d43f3f1@syzkaller.appspotmail.com>
Link: https://syzkaller.appspot.com/bug?extid=4913dca2ea6e4d43f3f1Signed-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>
parent 4ea2a8d8
...@@ -511,7 +511,11 @@ int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd) ...@@ -511,7 +511,11 @@ int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd)
if (type == HFSPLUS_FOLDER) { if (type == HFSPLUS_FOLDER) {
struct hfsplus_cat_folder *folder = &entry.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, hfs_bnode_read(fd->bnode, &entry, fd->entryoffset,
sizeof(struct hfsplus_cat_folder)); sizeof(struct hfsplus_cat_folder));
hfsplus_get_perms(inode, &folder->permissions, 1); hfsplus_get_perms(inode, &folder->permissions, 1);
...@@ -531,7 +535,11 @@ int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd) ...@@ -531,7 +535,11 @@ int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd)
} else if (type == HFSPLUS_FILE) { } else if (type == HFSPLUS_FILE) {
struct hfsplus_cat_file *file = &entry.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, hfs_bnode_read(fd->bnode, &entry, fd->entryoffset,
sizeof(struct hfsplus_cat_file)); sizeof(struct hfsplus_cat_file));
...@@ -562,6 +570,7 @@ int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd) ...@@ -562,6 +570,7 @@ int hfsplus_cat_read_inode(struct inode *inode, struct hfs_find_data *fd)
pr_err("bad catalog entry used to create inode\n"); pr_err("bad catalog entry used to create inode\n");
res = -EIO; res = -EIO;
} }
out:
return res; return res;
} }
...@@ -570,6 +579,7 @@ int hfsplus_cat_write_inode(struct inode *inode) ...@@ -570,6 +579,7 @@ int hfsplus_cat_write_inode(struct inode *inode)
struct inode *main_inode = inode; struct inode *main_inode = inode;
struct hfs_find_data fd; struct hfs_find_data fd;
hfsplus_cat_entry entry; hfsplus_cat_entry entry;
int res = 0;
if (HFSPLUS_IS_RSRC(inode)) if (HFSPLUS_IS_RSRC(inode))
main_inode = HFSPLUS_I(inode)->rsrc_inode; main_inode = HFSPLUS_I(inode)->rsrc_inode;
...@@ -588,7 +598,11 @@ int hfsplus_cat_write_inode(struct inode *inode) ...@@ -588,7 +598,11 @@ int hfsplus_cat_write_inode(struct inode *inode)
if (S_ISDIR(main_inode->i_mode)) { if (S_ISDIR(main_inode->i_mode)) {
struct hfsplus_cat_folder *folder = &entry.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, hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
sizeof(struct hfsplus_cat_folder)); sizeof(struct hfsplus_cat_folder));
/* simple node checks? */ /* simple node checks? */
...@@ -613,7 +627,11 @@ int hfsplus_cat_write_inode(struct inode *inode) ...@@ -613,7 +627,11 @@ int hfsplus_cat_write_inode(struct inode *inode)
} else { } else {
struct hfsplus_cat_file *file = &entry.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, hfs_bnode_read(fd.bnode, &entry, fd.entryoffset,
sizeof(struct hfsplus_cat_file)); sizeof(struct hfsplus_cat_file));
hfsplus_inode_write_fork(inode, &file->data_fork); hfsplus_inode_write_fork(inode, &file->data_fork);
...@@ -634,7 +652,7 @@ int hfsplus_cat_write_inode(struct inode *inode) ...@@ -634,7 +652,7 @@ int hfsplus_cat_write_inode(struct inode *inode)
set_bit(HFSPLUS_I_CAT_DIRTY, &HFSPLUS_I(inode)->flags); set_bit(HFSPLUS_I_CAT_DIRTY, &HFSPLUS_I(inode)->flags);
out: out:
hfs_find_exit(&fd); hfs_find_exit(&fd);
return 0; return res;
} }
int hfsplus_fileattr_get(struct dentry *dentry, struct fileattr *fa) int hfsplus_fileattr_get(struct dentry *dentry, struct fileattr *fa)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment