| From stable+bounces-272000-greg=kroah.com@vger.kernel.org Sun Jul 5 05:12:09 2026 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Sat, 4 Jul 2026 23:11:50 -0400 |
| Subject: NFSv4/flexfiles: reject zero filehandle version count |
| To: stable@vger.kernel.org |
| Cc: Michael Bommarito <michael.bommarito@gmail.com>, Anna Schumaker <anna.schumaker@hammerspace.com>, Sasha Levin <sashal@kernel.org> |
| Message-ID: <20260705031150.1600970-5-sashal@kernel.org> |
| |
| From: Michael Bommarito <michael.bommarito@gmail.com> |
| |
| [ Upstream commit 2c6bb3c40bc24f6aa8dfbe6fe98c3ad6389203f2 ] |
| |
| ff_layout_alloc_lseg() decodes the filehandle-version array count |
| from the flexfiles layout body. The value is used as the count for |
| kzalloc_objs(), and the current code only rejects NULL. |
| |
| A zero count yields ZERO_SIZE_PTR, which can be stored in |
| dss_info->fh_versions even though later flexfiles paths assume that at |
| least one filehandle version exists. |
| |
| Reject fh_count == 0 before the allocation, matching the existing zero |
| version_count validation in the flexfiles GETDEVICEINFO parser. |
| |
| A QEMU/KASAN run with a malformed flexfiles layout hit: |
| |
| KASAN: null-ptr-deref in range [0x0000000000000010-0x0000000000000017] |
| RIP: 0010:ff_layout_encode_ff_layoutupdate.isra.0+0x15f/0x750 |
| ff_layout_encode_layoutreturn+0x683/0x970 |
| nfs4_xdr_enc_layoutreturn+0x278/0x3a0 |
| Kernel panic - not syncing: Fatal exception |
| |
| The patched kernel rejects the malformed layout without KASAN/oops/panic, |
| and a valid fh_count=1 regression still opens, reads, and unmounts cleanly. |
| |
| Cc: stable@vger.kernel.org |
| Fixes: d67ae825a59d ("pnfs/flexfiles: Add the FlexFile Layout Driver") |
| Assisted-by: Claude:claude-opus-4-7 |
| Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com> |
| Signed-off-by: Anna Schumaker <anna.schumaker@hammerspace.com> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| --- |
| fs/nfs/flexfilelayout/flexfilelayout.c | 4 ++++ |
| 1 file changed, 4 insertions(+) |
| |
| --- a/fs/nfs/flexfilelayout/flexfilelayout.c |
| +++ b/fs/nfs/flexfilelayout/flexfilelayout.c |
| @@ -493,6 +493,10 @@ ff_layout_alloc_lseg(struct pnfs_layout_ |
| if (!p) |
| goto out_err_free; |
| fh_count = be32_to_cpup(p); |
| + if (fh_count == 0) { |
| + rc = -EINVAL; |
| + goto out_err_free; |
| + } |
| |
| fls->mirror_array[i]->dss[dss_id].fh_versions = |
| kcalloc(fh_count, sizeof(struct nfs_fh), |