Whamcloud - gitweb
libsupport: don't try accessing the project quota for 128 byte inodes
authorTheodore Ts'o <tytso@mit.edu>
Tue, 22 Aug 2017 04:54:15 +0000 (00:54 -0400)
committerTheodore Ts'o <tytso@mit.edu>
Tue, 22 Aug 2017 14:35:52 +0000 (10:35 -0400)
If the file system has 128 byte inode, it's not possible to access its
project quota id, since the inode is too small.  So prevent a
potential out-of-bounds read in get_qid().

The problem was found by valgrind and American Fuzzy Lop.

Address-Debian-Bug: #871540

Signed-off-by: Theodore Ts'o <tytso@mit.edu>
lib/support/mkquota.c

index 931a839..e65c95b 100644 (file)
@@ -249,6 +249,11 @@ static int dict_uint_cmp(const void *a, const void *b)
                return -1;
 }
 
+static inline int project_quota_valid(quota_ctx_t qctx)
+{
+       return (EXT2_INODE_SIZE(qctx->fs->super) > EXT2_GOOD_OLD_INODE_SIZE);
+}
+
 static inline qid_t get_qid(struct ext2_inode_large *inode, enum quota_type qtype)
 {
        unsigned int inode_size;
@@ -392,6 +397,8 @@ void quota_data_add(quota_ctx_t qctx, struct ext2_inode_large *inode,
                        inode_uid(*inode),
                        inode_gid(*inode), space);
        for (qtype = 0; qtype < MAXQUOTAS; qtype++) {
+               if (qtype == PRJQUOTA && !project_quota_valid(qctx))
+                       continue;
                dict = qctx->quota_dict[qtype];
                if (dict) {
                        dq = get_dq(dict, get_qid(inode, qtype));
@@ -419,6 +426,8 @@ void quota_data_sub(quota_ctx_t qctx, struct ext2_inode_large *inode,
                        inode_uid(*inode),
                        inode_gid(*inode), space);
        for (qtype = 0; qtype < MAXQUOTAS; qtype++) {
+               if (qtype == PRJQUOTA && !project_quota_valid(qctx))
+                       continue;
                dict = qctx->quota_dict[qtype];
                if (dict) {
                        dq = get_dq(dict, get_qid(inode, qtype));
@@ -444,6 +453,8 @@ void quota_data_inodes(quota_ctx_t qctx, struct ext2_inode_large *inode,
                        inode_uid(*inode),
                        inode_gid(*inode), adjust);
        for (qtype = 0; qtype < MAXQUOTAS; qtype++) {
+               if (qtype == PRJQUOTA && !project_quota_valid(qctx))
+                       continue;
                dict = qctx->quota_dict[qtype];
                if (dict) {
                        dq = get_dq(dict, get_qid(inode, qtype));