From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from userp1040.oracle.com ([156.151.31.81]:37892 "EHLO userp1040.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751292AbdANG2g (ORCPT ); Sat, 14 Jan 2017 01:28:36 -0500 Date: Fri, 13 Jan 2017 22:28:10 -0800 From: "Darrick J. Wong" Subject: Re: [PATCH v8 2/6] xfs: sanity check directory inode di_size Message-ID: <20170114062810.GG14038@birch.djwong.org> References: <1484123050-11064-1-git-send-email-amir73il@gmail.com> <1484123050-11064-3-git-send-email-amir73il@gmail.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <1484123050-11064-3-git-send-email-amir73il@gmail.com> Sender: linux-xfs-owner@vger.kernel.org List-ID: List-Id: xfs To: Amir Goldstein Cc: Brian Foster , Christoph Hellwig , linux-xfs@vger.kernel.org On Wed, Jan 11, 2017 at 10:24:06AM +0200, Amir Goldstein wrote: > This changes fixes an assertion hit when fuzzing on-disk > i_mode values. > > The easy case to fix is when changing an empty file > i_mode to S_IFDIR. In this case, xfs_dinode_verify() > detects an illegal zero size for directory and fails > to load the inode structure from disk. > > For the case of non empty file whose i_mode is changed > to S_IFDIR, the ASSERT() statement in xfs_dir2_isblock() > is replaced with return -EFSCORRUPTED, to avoid interacting > with corrupted jusk also when XFS_DEBUG is disabled. > > Suggested-by: Darrick J. Wong > Reviewed-by: Christoph Hellwig > Signed-off-by: Amir Goldstein > --- > fs/xfs/libxfs/xfs_dir2.c | 3 ++- > fs/xfs/libxfs/xfs_inode_buf.c | 7 +++++-- > 2 files changed, 7 insertions(+), 3 deletions(-) > > diff --git a/fs/xfs/libxfs/xfs_dir2.c b/fs/xfs/libxfs/xfs_dir2.c > index c58d72c..4f7913f 100644 > --- a/fs/xfs/libxfs/xfs_dir2.c > +++ b/fs/xfs/libxfs/xfs_dir2.c > @@ -631,7 +631,8 @@ xfs_dir2_isblock( > if ((rval = xfs_bmap_last_offset(args->dp, &last, XFS_DATA_FORK))) > return rval; > rval = XFS_FSB_TO_B(args->dp->i_mount, last) == args->geo->blksize; > - ASSERT(rval == 0 || args->dp->i_d.di_size == args->geo->blksize); > + if (rval != 0 && args->dp->i_d.di_size != args->geo->blksize) > + return -EFSCORRUPTED; > *vp = rval; > return 0; > } > diff --git a/fs/xfs/libxfs/xfs_inode_buf.c b/fs/xfs/libxfs/xfs_inode_buf.c > index dd483e2..0091ac3 100644 > --- a/fs/xfs/libxfs/xfs_inode_buf.c > +++ b/fs/xfs/libxfs/xfs_inode_buf.c > @@ -386,6 +386,7 @@ xfs_dinode_verify( > xfs_ino_t ino, > struct xfs_dinode *dip) > { > + uint16_t mode; > uint16_t flags; > uint64_t flags2; > > @@ -396,8 +397,10 @@ xfs_dinode_verify( > if (be64_to_cpu(dip->di_size) & (1ULL << 63)) > return false; > > - /* No zero-length symlinks. */ > - if (S_ISLNK(be16_to_cpu(dip->di_mode)) && dip->di_size == 0) > + mode = be16_to_cpu(dip->di_mode); > + > + /* No zero-length symlinks/dirs. */ > + if ((S_ISLNK(mode) || S_ISDIR(mode)) && dip->di_size == 0) Drat, I just hit this with the fuzzer tests, so I'll pull this in for rc5. Good work! :) --D > return false; > > /* only version 3 or greater inodes are extensively verified here */ > -- > 2.7.4 > > -- > To unsubscribe from this list: send the line "unsubscribe linux-xfs" in > the body of a message to majordomo@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html