| From stable+bounces-124376-greg=kroah.com@vger.kernel.org Thu Mar 13 21:26:36 2025 |
| From: Leah Rumancik <leah.rumancik@gmail.com> |
| Date: Thu, 13 Mar 2025 13:25:39 -0700 |
| Subject: xfs: don't allow overly small or large realtime volumes |
| To: stable@vger.kernel.org |
| Cc: xfs-stable@lists.linux.dev, "Darrick J. Wong" <djwong@kernel.org>, Christoph Hellwig <hch@lst.de>, Leah Rumancik <leah.rumancik@gmail.com> |
| Message-ID: <20250313202550.2257219-20-leah.rumancik@gmail.com> |
| |
| From: "Darrick J. Wong" <djwong@kernel.org> |
| |
| [ Upstream commit e14293803f4e84eb23a417b462b56251033b5a66 ] |
| |
| Don't allow realtime volumes that are less than one rt extent long. |
| This has been broken across 4 LTS kernels with nobody noticing, so let's |
| just disable it. |
| |
| Signed-off-by: Darrick J. Wong <djwong@kernel.org> |
| Reviewed-by: Christoph Hellwig <hch@lst.de> |
| Signed-off-by: Leah Rumancik <leah.rumancik@gmail.com> |
| Acked-by: "Darrick J. Wong" <djwong@kernel.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| fs/xfs/libxfs/xfs_rtbitmap.h | 13 +++++++++++++ |
| fs/xfs/libxfs/xfs_sb.c | 3 ++- |
| fs/xfs/xfs_rtalloc.c | 2 ++ |
| 3 files changed, 17 insertions(+), 1 deletion(-) |
| |
| --- a/fs/xfs/libxfs/xfs_rtbitmap.h |
| +++ b/fs/xfs/libxfs/xfs_rtbitmap.h |
| @@ -73,6 +73,18 @@ int xfs_rtfree_blocks(struct xfs_trans * |
| |
| uint8_t xfs_compute_rextslog(xfs_rtbxlen_t rtextents); |
| |
| +/* Do we support an rt volume having this number of rtextents? */ |
| +static inline bool |
| +xfs_validate_rtextents( |
| + xfs_rtbxlen_t rtextents) |
| +{ |
| + /* No runt rt volumes */ |
| + if (rtextents == 0) |
| + return false; |
| + |
| + return true; |
| +} |
| + |
| #else /* CONFIG_XFS_RT */ |
| # define xfs_rtfree_extent(t,b,l) (-ENOSYS) |
| # define xfs_rtfree_blocks(t,rb,rl) (-ENOSYS) |
| @@ -81,6 +93,7 @@ uint8_t xfs_compute_rextslog(xfs_rtbxlen |
| # define xfs_rtbuf_get(m,t,b,i,p) (-ENOSYS) |
| # define xfs_rtalloc_extent_is_free(m,t,s,l,i) (-ENOSYS) |
| # define xfs_compute_rextslog(rtx) (0) |
| +# define xfs_validate_rtextents(rtx) (false) |
| #endif /* CONFIG_XFS_RT */ |
| |
| #endif /* __XFS_RTBITMAP_H__ */ |
| --- a/fs/xfs/libxfs/xfs_sb.c |
| +++ b/fs/xfs/libxfs/xfs_sb.c |
| @@ -502,7 +502,8 @@ xfs_validate_sb_common( |
| rbmblocks = howmany_64(sbp->sb_rextents, |
| NBBY * sbp->sb_blocksize); |
| |
| - if (sbp->sb_rextents != rexts || |
| + if (!xfs_validate_rtextents(rexts) || |
| + sbp->sb_rextents != rexts || |
| sbp->sb_rextslog != xfs_compute_rextslog(rexts) || |
| sbp->sb_rbmblocks != rbmblocks) { |
| xfs_notice(mp, |
| --- a/fs/xfs/xfs_rtalloc.c |
| +++ b/fs/xfs/xfs_rtalloc.c |
| @@ -998,6 +998,8 @@ xfs_growfs_rt( |
| */ |
| nrextents = nrblocks; |
| do_div(nrextents, in->extsize); |
| + if (!xfs_validate_rtextents(nrextents)) |
| + return -EINVAL; |
| nrbmblocks = howmany_64(nrextents, NBBY * sbp->sb_blocksize); |
| nrextslog = xfs_compute_rextslog(nrextents); |
| nrsumlevels = nrextslog + 1; |