aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Kara <jack@suse.cz>2015-03-04 08:42:02 -0500
committerJan Kara <jack@suse.cz>2015-03-04 10:42:46 -0500
commit7e08da50cf706151f324349f9235ebd311226997 (patch)
tree3573b83be3cf4f8ee26c92b91d7aad3a4892ef5a
parent781970240a56d1c15a9b8ee37d28987b8182f060 (diff)
quota: Fix maximum quota limit settings
Currently quota format that supports 64-bit usage sets maximum quota limit as 2^64-1. However quota core code uses signed numbers to track usage and even limits themselves are stored in long long. Checking of maximum allowable limits worked by luck until commit 14bf61ffe6ac (quota: Switch ->get_dqblk() and ->set_dqblk() to use bytes as space units) because variable we compared with was unsigned. After that commit the type we compared against changed to signed and thus checks for maximum limits with the newest VFS quota format started to refuse any non-negative value. Later the problem was inadvertedly fixed by commit b10a08194c2b (quota: Store maximum space limit in bytes) because we started to compare against unsigned type as well. Fix possible future problems of this kind by setting maximum limits to 2^63-1 to avoid overflow issues. Reported-by: Carlos Carvalho <carlos@fisica.ufpr.br> Signed-off-by: Jan Kara <jack@suse.cz>
-rw-r--r--fs/quota/quota_v2.c12
1 files changed, 8 insertions, 4 deletions
diff --git a/fs/quota/quota_v2.c b/fs/quota/quota_v2.c
index 9cb10d7197f7..2aa012a68e90 100644
--- a/fs/quota/quota_v2.c
+++ b/fs/quota/quota_v2.c
@@ -117,12 +117,16 @@ static int v2_read_file_info(struct super_block *sb, int type)
117 qinfo = info->dqi_priv; 117 qinfo = info->dqi_priv;
118 if (version == 0) { 118 if (version == 0) {
119 /* limits are stored as unsigned 32-bit data */ 119 /* limits are stored as unsigned 32-bit data */
120 info->dqi_max_spc_limit = 0xffffffffULL << QUOTABLOCK_BITS; 120 info->dqi_max_spc_limit = 0xffffffffLL << QUOTABLOCK_BITS;
121 info->dqi_max_ino_limit = 0xffffffff; 121 info->dqi_max_ino_limit = 0xffffffff;
122 } else { 122 } else {
123 /* used space is stored as unsigned 64-bit value in bytes */ 123 /*
124 info->dqi_max_spc_limit = 0xffffffffffffffffULL; /* 2^64-1 */ 124 * Used space is stored as unsigned 64-bit value in bytes but
125 info->dqi_max_ino_limit = 0xffffffffffffffffULL; 125 * quota core supports only signed 64-bit values so use that
126 * as a limit
127 */
128 info->dqi_max_spc_limit = 0x7fffffffffffffffLL; /* 2^63-1 */
129 info->dqi_max_ino_limit = 0x7fffffffffffffffLL;
126 } 130 }
127 info->dqi_bgrace = le32_to_cpu(dinfo.dqi_bgrace); 131 info->dqi_bgrace = le32_to_cpu(dinfo.dqi_bgrace);
128 info->dqi_igrace = le32_to_cpu(dinfo.dqi_igrace); 132 info->dqi_igrace = le32_to_cpu(dinfo.dqi_igrace);