tags 871540 +pending
thanks

Thanks for reporting this bug.  The following fix will be in the next
release of e2fsprogs.

                                                - Ted

commit 75153dae6e0a9807e2c57fcc9fb3bb23dc7c19cc
Author: Theodore Ts'o <ty...@mit.edu>
Date:   Tue Aug 22 00:54:15 2017 -0400

    libsupport: don't try accessing the project quota for 128 byte inodes
    
    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 <ty...@mit.edu>

diff --git a/lib/support/mkquota.c b/lib/support/mkquota.c
index 931a839dd..e65c95b76 100644
--- a/lib/support/mkquota.c
+++ b/lib/support/mkquota.c
@@ -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));

Reply via email to