diff --git a/fs/gfs2/ops_fstype.c b/fs/gfs2/ops_fstype.c index e83d293c3614..ef88db62c5b0 100644 --- a/fs/gfs2/ops_fstype.c +++ b/fs/gfs2/ops_fstype.c @@ -281,9 +281,23 @@ static int gfs2_read_sb(struct gfs2_sbd *sdp, int silent) sdp->sd_ldptrs = (sdp->sd_sb.sb_bsize - sizeof(struct gfs2_log_descriptor)) / sizeof(u64); sdp->sd_jbsize = sdp->sd_sb.sb_bsize - sizeof(struct gfs2_meta_header); + + /* Validate sb_bsize and derived sd_hash_ptrs */ + if (sdp->sd_sb.sb_bsize < 512 || sdp->sd_sb.sb_bsize % 512 != 0) { + fs_err(sdp, "Invalid sb_bsize: %u\n", sdp->sd_sb.sb_bsize); + return -EINVAL; + } + sdp->sd_hash_bsize = sdp->sd_sb.sb_bsize / 2; sdp->sd_hash_bsize_shift = sdp->sd_sb.sb_bsize_shift - 1; sdp->sd_hash_ptrs = sdp->sd_hash_bsize / sizeof(u64); + + if (sdp->sd_hash_ptrs == 0 || !is_power_of_2(sdp->sd_hash_ptrs)) { + fs_err(sdp, "Invalid sd_hash_ptrs: %u (sb_bsize = %u)\n", + sdp->sd_hash_ptrs, sdp->sd_sb.sb_bsize); + return -EFSCORRUPTED; + } + sdp->sd_qc_per_block = (sdp->sd_sb.sb_bsize - sizeof(struct gfs2_meta_header)) / sizeof(struct gfs2_quota_change);