From: Theodore Ts'o Date: Tue, 22 Aug 2017 04:54:15 +0000 (-0400) Subject: libsupport: don't try accessing the project quota for 128 byte inodes X-Git-Tag: v1.43.6~18 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9e54816b22afcfb5ac597506e8210b42eeac5553;p=thirdparty%2Fe2fsprogs.git 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 --- 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));