Commit 10f04d40 authored by Jan Kara's avatar Jan Kara

quota: Don't overflow quota file offsets

The on-disk quota format supports quota files with upto 2^32 blocks. Be
careful when computing quota file offsets in the quota files from block
numbers as they can overflow 32-bit types. Since quota files larger than
4GB would require ~26 millions of quota users, this is mostly a
theoretical concern now but better be careful, fuzzers would find the
problem sooner or later anyway...
Reviewed-by: default avatarAndreas Dilger <adilger@dilger.ca>
Signed-off-by: default avatarJan Kara <jack@suse.cz>
parent a219ee41
...@@ -62,7 +62,7 @@ static ssize_t read_blk(struct qtree_mem_dqinfo *info, uint blk, char *buf) ...@@ -62,7 +62,7 @@ static ssize_t read_blk(struct qtree_mem_dqinfo *info, uint blk, char *buf)
memset(buf, 0, info->dqi_usable_bs); memset(buf, 0, info->dqi_usable_bs);
return sb->s_op->quota_read(sb, info->dqi_type, buf, return sb->s_op->quota_read(sb, info->dqi_type, buf,
info->dqi_usable_bs, blk << info->dqi_blocksize_bits); info->dqi_usable_bs, (loff_t)blk << info->dqi_blocksize_bits);
} }
static ssize_t write_blk(struct qtree_mem_dqinfo *info, uint blk, char *buf) static ssize_t write_blk(struct qtree_mem_dqinfo *info, uint blk, char *buf)
...@@ -71,7 +71,7 @@ static ssize_t write_blk(struct qtree_mem_dqinfo *info, uint blk, char *buf) ...@@ -71,7 +71,7 @@ static ssize_t write_blk(struct qtree_mem_dqinfo *info, uint blk, char *buf)
ssize_t ret; ssize_t ret;
ret = sb->s_op->quota_write(sb, info->dqi_type, buf, ret = sb->s_op->quota_write(sb, info->dqi_type, buf,
info->dqi_usable_bs, blk << info->dqi_blocksize_bits); info->dqi_usable_bs, (loff_t)blk << info->dqi_blocksize_bits);
if (ret != info->dqi_usable_bs) { if (ret != info->dqi_usable_bs) {
quota_error(sb, "dquota write failed"); quota_error(sb, "dquota write failed");
if (ret >= 0) if (ret >= 0)
...@@ -284,7 +284,7 @@ static uint find_free_dqentry(struct qtree_mem_dqinfo *info, ...@@ -284,7 +284,7 @@ static uint find_free_dqentry(struct qtree_mem_dqinfo *info,
blk); blk);
goto out_buf; goto out_buf;
} }
dquot->dq_off = (blk << info->dqi_blocksize_bits) + dquot->dq_off = ((loff_t)blk << info->dqi_blocksize_bits) +
sizeof(struct qt_disk_dqdbheader) + sizeof(struct qt_disk_dqdbheader) +
i * info->dqi_entry_size; i * info->dqi_entry_size;
kfree(buf); kfree(buf);
...@@ -559,7 +559,7 @@ static loff_t find_block_dqentry(struct qtree_mem_dqinfo *info, ...@@ -559,7 +559,7 @@ static loff_t find_block_dqentry(struct qtree_mem_dqinfo *info,
ret = -EIO; ret = -EIO;
goto out_buf; goto out_buf;
} else { } else {
ret = (blk << info->dqi_blocksize_bits) + sizeof(struct ret = ((loff_t)blk << info->dqi_blocksize_bits) + sizeof(struct
qt_disk_dqdbheader) + i * info->dqi_entry_size; qt_disk_dqdbheader) + i * info->dqi_entry_size;
} }
out_buf: out_buf:
......
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