On Mon, Oct 28, 2019 at 09:04:05PM -0700, Darrick J. Wong wrote: > From: Darrick J. Wong <darrick.wong@xxxxxxxxxx> > > Actually call namecheck on directory entry names before we hand them > over to userspace. > > Signed-off-by: Darrick J. Wong <darrick.wong@xxxxxxxxxx> > Reviewed-by: Christoph Hellwig <hch@xxxxxx> > --- Reviewed-by: Brian Foster <bfoster@xxxxxxxxxx> > fs/xfs/xfs_dir2_readdir.c | 27 ++++++++++++++++++++++----- > 1 file changed, 22 insertions(+), 5 deletions(-) > > > diff --git a/fs/xfs/xfs_dir2_readdir.c b/fs/xfs/xfs_dir2_readdir.c > index 283df898dd9f..a0bec0931f3b 100644 > --- a/fs/xfs/xfs_dir2_readdir.c > +++ b/fs/xfs/xfs_dir2_readdir.c > @@ -17,6 +17,7 @@ > #include "xfs_trace.h" > #include "xfs_bmap.h" > #include "xfs_trans.h" > +#include "xfs_error.h" > > /* > * Directory file type support functions > @@ -115,6 +116,11 @@ xfs_dir2_sf_getdents( > ino = dp->d_ops->sf_get_ino(sfp, sfep); > filetype = dp->d_ops->sf_get_ftype(sfep); > ctx->pos = off & 0x7fffffff; > + if (!xfs_dir2_namecheck(sfep->name, sfep->namelen)) { > + XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, > + dp->i_mount); > + return -EFSCORRUPTED; > + } > if (!dir_emit(ctx, (char *)sfep->name, sfep->namelen, ino, > xfs_dir3_get_dtype(dp->i_mount, filetype))) > return 0; > @@ -208,12 +214,16 @@ xfs_dir2_block_getdents( > /* > * If it didn't fit, set the final offset to here & return. > */ > + if (!xfs_dir2_namecheck(dep->name, dep->namelen)) { > + XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, > + dp->i_mount); > + error = -EFSCORRUPTED; > + goto out_rele; > + } > if (!dir_emit(ctx, (char *)dep->name, dep->namelen, > be64_to_cpu(dep->inumber), > - xfs_dir3_get_dtype(dp->i_mount, filetype))) { > - xfs_trans_brelse(args->trans, bp); > - return 0; > - } > + xfs_dir3_get_dtype(dp->i_mount, filetype))) > + goto out_rele; > } > > /* > @@ -222,8 +232,9 @@ xfs_dir2_block_getdents( > */ > ctx->pos = xfs_dir2_db_off_to_dataptr(geo, geo->datablk + 1, 0) & > 0x7fffffff; > +out_rele: > xfs_trans_brelse(args->trans, bp); > - return 0; > + return error; > } > > /* > @@ -456,6 +467,12 @@ xfs_dir2_leaf_getdents( > filetype = dp->d_ops->data_get_ftype(dep); > > ctx->pos = xfs_dir2_byte_to_dataptr(curoff) & 0x7fffffff; > + if (!xfs_dir2_namecheck(dep->name, dep->namelen)) { > + XFS_ERROR_REPORT(__func__, XFS_ERRLEVEL_LOW, > + dp->i_mount); > + error = -EFSCORRUPTED; > + break; > + } > if (!dir_emit(ctx, (char *)dep->name, dep->namelen, > be64_to_cpu(dep->inumber), > xfs_dir3_get_dtype(dp->i_mount, filetype))) >