From: Jan Kara <j...@suse.cz>

commit 11c514a99bb960941535134f0587102855e8ddee upstream.

Perform basic sanity checks of quota headers to avoid kernel crashes on
corrupted quota files.

CC: sta...@vger.kernel.org
Reported-by: syzbot+f816042a7ae2225f2...@syzkaller.appspotmail.com
Reviewed-by: Andreas Dilger <adil...@dilger.ca>
Signed-off-by: Jan Kara <j...@suse.cz>
Signed-off-by: Greg Kroah-Hartman <gre...@linuxfoundation.org>

---
 fs/quota/quota_v2.c |   19 +++++++++++++++++++
 1 file changed, 19 insertions(+)

--- a/fs/quota/quota_v2.c
+++ b/fs/quota/quota_v2.c
@@ -158,6 +158,25 @@ static int v2_read_file_info(struct supe
                qinfo->dqi_entry_size = sizeof(struct v2r1_disk_dqblk);
                qinfo->dqi_ops = &v2r1_qtree_ops;
        }
+       ret = -EUCLEAN;
+       /* Some sanity checks of the read headers... */
+       if ((loff_t)qinfo->dqi_blocks << qinfo->dqi_blocksize_bits >
+           i_size_read(sb_dqopt(sb)->files[type])) {
+               quota_error(sb, "Number of blocks too big for quota file size 
(%llu > %llu).",
+                   (loff_t)qinfo->dqi_blocks << qinfo->dqi_blocksize_bits,
+                   i_size_read(sb_dqopt(sb)->files[type]));
+               goto out;
+       }
+       if (qinfo->dqi_free_blk >= qinfo->dqi_blocks) {
+               quota_error(sb, "Free block number too big (%u >= %u).",
+                           qinfo->dqi_free_blk, qinfo->dqi_blocks);
+               goto out;
+       }
+       if (qinfo->dqi_free_entry >= qinfo->dqi_blocks) {
+               quota_error(sb, "Block with free entry too big (%u >= %u).",
+                           qinfo->dqi_free_entry, qinfo->dqi_blocks);
+               goto out;
+       }
        ret = 0;
 out:
        up_read(&dqopt->dqio_sem);


Reply via email to