diff --git a/fs/nilfs2/recovery.c b/fs/nilfs2/recovery.c index abe4101f7550..c384325a57d0 100644 --- a/fs/nilfs2/recovery.c +++ b/fs/nilfs2/recovery.c @@ -545,6 +545,23 @@ static int nilfs_recover_dsync_blocks(struct the_nilfs *nilfs, goto failed_inode; } + /* + * Regular files, directories, and symlinks are the only + * inode types with data blocks and an initialized bmap; + * a crafted image can reference some other inode type + * here, whose i_bmap_data was never set up by + * __nilfs_read_inode(). + */ + if (!likely(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || + S_ISLNK(inode->i_mode))) { + nilfs_warn(sb, + "%s: invalid inode type (ino=%lu, mode=0%o)", + __func__, (unsigned long)rb->ino, + inode->i_mode); + err = -EINVAL; + goto failed_inode; + } + pos = rb->blkoff << inode->i_blkbits; err = block_write_begin(inode->i_mapping, pos, blocksize, &folio, nilfs_get_block);